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 yError() << txt << " is not yet implemented for embObjMotionControl";
58 return true;
59}
60
61static inline bool DEPRECATED(const char *txt)
62{
63 yError() << txt << " has been deprecated for embObjMotionControl";
64 return true;
65}
66
67#define NV_NOT_FOUND return nv_not_found();
68
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
1048
1050 if(! _mcparser->parseTimeoutsGroup(config, _timeouts, 1000 /*defaultVelocityTimeout*/))
1051 return false;
1052
1053
1054 return true;
1055}
1056
1057
1058
1059bool embObjMotionControl::verifyUseMotorSpeedFbkInJointSet(int useMotorSpeedFbk [])
1060{
1061 for(size_t s=0; s< _jsets.size(); s++)
1062 {
1063 int numofjointsinset = _jsets[s].getNumberofJoints();
1064 if(numofjointsinset == 0 )
1065 {
1066 yError() << "embObjMC " << getBoardInfo() << "Jointsset " << s << "hasn't joints!!! I should be never stay here!!!";
1067 return false;
1068 }
1069
1070 int firstjointofset = _jsets[s].joints[0];
1071 for(int j=1; j<numofjointsinset; j++)
1072 {
1073 int joint = _jsets[s].joints[j];
1074 if(useMotorSpeedFbk[firstjointofset] != useMotorSpeedFbk[joint])
1075 {
1076 yError() << "embObjMC " << getBoardInfo() << ". Param useMotorSpeedFbk should have same value for joints belong same set. See joint " << firstjointofset << " and " << joint;
1077 return false;
1078 }
1079 }
1080
1081 _jsets[s].setUseSpeedFeedbackFromMotors(useMotorSpeedFbk[firstjointofset]);
1082 }
1083
1084 return true;
1085
1086}
1087
1088bool embObjMotionControl::verifyTorquePidshasSameUnitTypes(yarp::dev::PidFeedbackUnitsEnum &fbk_pidunits, yarp::dev::PidOutputUnitsEnum& out_pidunits)
1089{
1090 fbk_pidunits = yarp::dev::PidFeedbackUnitsEnum::RAW_MACHINE_UNITS;
1091 out_pidunits = yarp::dev::PidOutputUnitsEnum::RAW_MACHINE_UNITS;
1092 //get first joint with enabled torque
1093 int firstjoint = -1;
1094 for(int i=0; i<_njoints; i++)
1095 {
1096 if(_trq_pids[i].enabled)
1097 firstjoint = i;
1098 }
1099
1100 if(firstjoint==-1)
1101 {
1102 // no joint has torque enabed
1103 return true;
1104 }
1105
1106 for(int i=firstjoint+1; i<_njoints; i++)
1107 {
1108 if(_trq_pids[i].enabled)
1109 {
1110 if(_trq_pids[firstjoint].fbk_PidUnits != _trq_pids[i].fbk_PidUnits ||
1111 _trq_pids[firstjoint].out_PidUnits != _trq_pids[i].out_PidUnits)
1112 {
1113 yError() << "embObjMC " << getBoardInfo() << "all joints with torque enabled should have same controlunits type. Joint " << firstjoint << " differs from joint " << i;
1114 return false;
1115 }
1116 }
1117 }
1118
1119 fbk_pidunits = _trq_pids[firstjoint].fbk_PidUnits;
1120 out_pidunits = _trq_pids[firstjoint].out_PidUnits;
1121 return true;
1122}
1123
1124bool embObjMotionControl::isTorqueControlEnabled(int joint)
1125{
1126 return (_trq_pids[joint].enabled);
1127}
1128
1129bool embObjMotionControl::isVelocityControlEnabled(int joint)
1130{
1131 //return (_dir_pids[joint].enabled);
1132 return (_trj_pids[joint].enabled);
1133}
1134
1135
1136void embObjMotionControl::updateDeadZoneWithDefaultValues(void)
1137{
1138 for(int i=0; i<_njoints; i++)
1139 {
1140 switch(_jointEncs[i].type)
1141 {
1142 case eomc_enc_aea:
1143 _deadzone[i] = eomc_defaultValue::DeadZone::jointWithAEA;// 0.0494;
1144 break;
1145 case eomc_enc_aea3:
1146 _deadzone[i] = eomc_defaultValue::DeadZone::jointWithAEA3;// TODO: temporary equal to 0.0
1147 break;
1148 case eomc_enc_aksim2:
1150 case eomc_enc_amo:
1151 _deadzone[i] = eomc_defaultValue::DeadZone::jointWithAMO;// 0.0055;
1152 break;
1153 case eomc_enc_roie:
1154 case eomc_enc_absanalog:
1155 case eomc_enc_mais:
1156 case eomc_enc_qenc:
1157 case eomc_enc_hallmotor:
1158 case eomc_enc_spichainof2:
1159 case eomc_enc_spichainof3:
1160 case eomc_enc_mrie:
1161 default:
1162 _deadzone[i] = 0.0;
1163
1164 }
1165 }
1166}
1167
1168// use this one for ... service configuration
1169bool embObjMotionControl::fromConfig_readServiceCfg(yarp::os::Searchable &config)
1170{
1171
1172 if(false == parser->parseService(config, serviceConfig))
1173 {
1174 yError() << "embObjMC " << getBoardInfo() << "cannot parse service" ;
1175 return false;
1176 }
1177
1178 if(eomn_serv_MC_generic == serviceConfig.ethservice.configuration.type)
1179 {
1180 yError() << "embObjMC " << getBoardInfo() << "it is no longer possible use eomn_serv_MC_generic, because firmware cannot configure itself!" ;
1181 return false;
1182 }
1183
1184 //now parser read encoders' resolutions also.
1185 //so here I save in embObMotioncontrol memory encoders's resolution
1186 servMC_encoder_t * jointEncoder_ptr = NULL;
1187 servMC_encoder_t * motorEncoder_ptr = NULL;
1188 for(int i=0; i<_njoints; i++)
1189 {
1190 jointEncoder_ptr = parser->getEncoderAtJoint(i);
1191 motorEncoder_ptr = parser->getEncoderAtMotor(i);
1192
1193 if(NULL == jointEncoder_ptr)
1194 {
1195 _jointEncs[i].resolution = 1;
1196 _jointEncs[i].type = eomc_enc_none;
1197 _jointEncs[i].tolerance = 0;
1198 }
1199 else
1200 {
1201 _jointEncs[i].resolution = jointEncoder_ptr->resolution;
1202 _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
1203 _jointEncs[i].tolerance = jointEncoder_ptr->tolerance;
1204 }
1205
1206
1207 if(NULL == motorEncoder_ptr)
1208 {
1209 _motorEncs[i].resolution = 1;
1210 _motorEncs[i].type = eomc_enc_none;
1211 _motorEncs[i].tolerance = 0;
1212 }
1213 else
1214 {
1215 _motorEncs[i].resolution = motorEncoder_ptr->resolution;
1216 _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
1217 _motorEncs[i].tolerance = motorEncoder_ptr->tolerance;
1218 }
1219
1220
1221 }
1222
1223
1224 return true;
1225}
1226
1227
1228
1229bool embObjMotionControl::fromConfig(yarp::os::Searchable &config)
1230{
1231
1232 _njoints = fromConfig_NumOfJoints(config);
1233
1234 if(0 == _njoints)
1235 {
1236 yError() << "embObjMC"<< getBoardInfo() << "fromConfig(): detected _njoints = " << _njoints;
1237 return false;
1238 }
1239
1240 // we have number of joints inside _njoints. we allocate all required buffers
1241 if(!alloc(_njoints))
1242 {
1243 yError() << "embObjMC"<< getBoardInfo() << "fromConfig(): alloc() failed for _njoints = " << _njoints;
1244 return false;
1245 }
1246
1247
1248 _mcparser = new eomc::Parser(_njoints, string(res->getProperties().boardnameString));
1249
1251 int currentMCversion =0;
1252 if(!_mcparser->parseMotioncontrolVersion(config, currentMCversion))
1253 return false;
1254
1255 if (currentMCversion != PARSER_MOTION_CONTROL_VERSION)
1256 {
1257 yError() << "embObjMC" << getBoardInfo() << "------ ATTENTION!!!! Wrong value of <MotioncontrolVersion> parameter !!!! ---------------------------------------------------------------------------------------";
1258 yError() << "embObjMC" << getBoardInfo() << "------ This means that the configuration files of this device are not compatible with my parser, so I cannot start. ";
1259 yError() << "embObjMC" << getBoardInfo() << "------ I need version " << PARSER_MOTION_CONTROL_VERSION << ", but in configuration files have version " << currentMCversion << ".";
1260 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). ";
1261 yError() << "embObjMC" << getBoardInfo() << "------ If the problem persists contact icub-support@iit.it DO NOT DO IT BY YOURSELF.";
1262 yError() << "embObjMC" << getBoardInfo() << "----------------------------------------------------------------------------------------------------------------------------------------------------------------";
1263 return false;
1264 }
1265
1266 //print verbose info
1267 if(_mcparser->isVerboseEnabled(config))
1268 yTrace() << config.toString().c_str();
1269
1270
1271
1272 // first step of configuration
1273 if(false == fromConfig_readServiceCfg(config))
1274 {
1275 return false;
1276 }
1277
1278 if(!_mcparser->parseBehaviourFalgs(config, behFlags.useRawEncoderData, behFlags.pwmIsLimited ))//in general info group
1279 {
1280 return false;
1281 }
1282
1283 if (!_mcparser->parseMaintenanceModeGroup(config, _maintenanceModeCfg.enableSkipRecalibration))// in general maintenance group
1284 {
1285 return false;
1286 }
1287
1288 // second step of configuration
1289 if(false == fromConfig_Step2(config))
1290 {
1291 return false;
1292 }
1293
1294 // third step of configuration
1295
1296
1297 return true;
1298}
1299
1300
1301bool embObjMotionControl::init()
1302{
1303 eOprotID32_t protid = 0;
1304
1306 //SEND DISABLE TO ALL JOINTS
1308
1309 for(int logico=0; logico< _njoints; logico++)
1310 {
1311 int fisico = _axisMap[logico];
1312 protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, fisico, eoprot_tag_mc_joint_cmmnds_controlmode);
1313 eOenum08_t controlMode = eomc_controlmode_cmd_idle;
1314
1315 if(false == res->setRemoteValue(protid, &controlMode))
1316 {
1317 yError() << "embObjMotionControl::init() had an error while setting eomc_controlmode_cmd_idle in "<< getBoardInfo();
1318 // return(false); i dont return false. because even if a failure, that is not a severe error.
1319 // MOREOVER: to verify we must read the status of the joint and NOT the command ... THINK OF IT
1320 }
1321 }
1322
1323 SystemClock::delaySystem(0.010);
1324
1325
1327 // configure the regular rops
1329
1330 vector<eOprotID32_t> id32v(0);
1331 for(int n=0; n<_njoints; n++)
1332 {
1333 protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, n, eoprot_tag_mc_joint_status_core);
1334 id32v.push_back(protid);
1335 protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, n, eoprot_tag_mc_joint_status_addinfo_multienc);
1336 id32v.push_back(protid);
1337 protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, n, eoprot_tag_mc_motor_status);
1338 id32v.push_back(protid);
1339 }
1340
1341 if(eomn_serv_diagn_mode_MC_AMOyarp == mcdiagnostics.config.mode)
1342 {
1343 protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, 0, eoprot_tag_mc_joint_status_debug);
1344 id32v.push_back(protid);
1345 protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, 1, eoprot_tag_mc_joint_status_debug);
1346 id32v.push_back(protid);
1347 }
1348
1349
1350 if(false == res->serviceSetRegulars(eomn_serv_category_mc, id32v))
1351 {
1352 yError() << "embObjMotionControl::init() fails to add its variables to regulars in "<< getBoardInfo() << ": cannot proceed any further";
1353 return false;
1354 }
1355 else
1356 {
1357 if(behFlags.verbosewhenok)
1358 {
1359 yDebug() << "embObjMotionControl::init() added" << id32v.size() << "regular rops to "<< getBoardInfo();
1360 char nvinfo[128];
1361 for(unsigned int r=0; r<id32v.size(); r++)
1362 {
1363 uint32_t id32 = id32v.at(r);
1364 eoprot_ID2information(id32, nvinfo, sizeof(nvinfo));
1365 yDebug() << "\t it added regular rop for" << nvinfo;
1366 }
1367 }
1368 }
1369
1370 SystemClock::delaySystem(0.005);
1371
1372
1373
1375 // invia la configurazione dei GIUNTI //
1377 for(int logico=0; logico< _njoints; logico++)
1378 {
1379 int fisico = _axisMap[logico];
1380 protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, fisico, eoprot_tag_mc_joint_config);
1381
1382 eOmc_joint_config_t jconfig = {0};
1383 memset(&jconfig, 0, sizeof(eOmc_joint_config_t));
1384 yarp::dev::Pid tmp;
1385 tmp = _measureConverter->convert_pid_to_machine(yarp::dev::VOCAB_PIDTYPE_POSITION,_trj_pids[logico].pid, fisico);
1386 copyPid_iCub2eo(&tmp, &jconfig.pidtrajectory);
1387 //tmp = _measureConverter->convert_pid_to_machine(yarp::dev::VOCAB_PIDTYPE_DIRECT, _dir_pids[logico].pid, fisico);
1388 //copyPid_iCub2eo(&tmp, &jconfig.piddirect);
1389 tmp = _measureConverter->convert_pid_to_machine(yarp::dev::VOCAB_PIDTYPE_TORQUE, _trq_pids[logico].pid, fisico);
1390 copyPid_iCub2eo(&tmp, &jconfig.pidtorque);
1391
1392 //stiffness and damping read in xml file are in Nm/deg and Nm/(Deg/sec), so we need to convert before send to fw.
1393 jconfig.impedance.damping = (eOmeas_damping_t) _measureConverter->impN2S(_impedance_params[logico].damping, fisico);
1394 jconfig.impedance.stiffness = (eOmeas_stiffness_t) _measureConverter->impN2S(_impedance_params[logico].stiffness, fisico);
1395 jconfig.impedance.offset = 0;
1396
1397 _cacheImpedance[logico].stiffness = jconfig.impedance.stiffness;
1398 _cacheImpedance[logico].damping = jconfig.impedance.damping;
1399 _cacheImpedance[logico].offset = jconfig.impedance.offset;
1400
1401 jconfig.userlimits.max = (eOmeas_position_t) S_32(_measureConverter->posA2E(_jointsLimits[logico].posMax, fisico));
1402 jconfig.userlimits.min = (eOmeas_position_t) S_32(_measureConverter->posA2E(_jointsLimits[logico].posMin, fisico));
1403
1404 jconfig.hardwarelimits.max = (eOmeas_position_t) S_32(_measureConverter->posA2E(_jointsLimits[logico].posHwMax, fisico));
1405 jconfig.hardwarelimits.min = (eOmeas_position_t) S_32(_measureConverter->posA2E(_jointsLimits[logico].posHwMin, fisico));
1406
1407
1408 jconfig.maxvelocityofjoint = S_32(_measureConverter->posA2E(_jointsLimits[logico].velMax, fisico)); //icubdeg/s
1409 jconfig.velocitysetpointtimeout = (eOmeas_time_t) U_16(_timeouts[logico].velocity);
1410
1411 jconfig.jntEncoderResolution = _jointEncs[logico].resolution;
1412 jconfig.jntEncoderType = _jointEncs[logico].type;
1413 jconfig.jntEncTolerance = _jointEncs[logico].tolerance;
1414
1415 jconfig.motor_params.bemf_value = _measureConverter->bemf_user2raw(_trq_pids[logico].kbemf, fisico);
1416 jconfig.motor_params.bemf_scale = 0;
1417 jconfig.motor_params.ktau_value = _measureConverter->ktau_user2raw(_trq_pids[logico].ktau, fisico);
1418 jconfig.motor_params.ktau_scale = 0;
1419 jconfig.motor_params.friction.viscous_pos_val = _measureConverter->viscousPos_user2raw(_trq_pids[logico].viscousPos, fisico);
1420 jconfig.motor_params.friction.viscous_neg_val = _measureConverter->viscousNeg_user2raw(_trq_pids[logico].viscousNeg, fisico);
1421 jconfig.motor_params.friction.coulomb_pos_val = _measureConverter->coulombPos_user2raw(_trq_pids[logico].coulombPos, fisico);
1422 jconfig.motor_params.friction.coulomb_neg_val = _measureConverter->coulombNeg_user2raw(_trq_pids[logico].coulombNeg, fisico);
1423 jconfig.motor_params.friction.velocityThres_val = _measureConverter->velocityThres_user2raw(_trq_pids[logico].velocityThres, fisico);
1424
1425 jconfig.gearbox_E2J = _gearbox_E2J[logico];
1426
1427 jconfig.deadzone = _measureConverter->posA2E(_deadzone[logico], fisico);
1428
1429 jconfig.tcfiltertype=_trq_pids[logico].filterType;
1430
1431 jconfig.kalman_params.enabled = _kalman_params[logico].enabled;
1432 for(int i=0; i<_kalman_params[logico].x0.size(); i++) jconfig.kalman_params.x0[i] = _kalman_params[logico].x0.at(i);
1433 for(int i=0; i<_kalman_params[logico].Q.size(); i++) jconfig.kalman_params.Q[i] = _kalman_params[logico].Q.at(i);
1434 jconfig.kalman_params.R = _kalman_params[logico].R;
1435 jconfig.kalman_params.P0 = _kalman_params[logico].P0;
1436
1437 if(false == res->setcheckRemoteValue(protid, &jconfig, 10, 0.010, 0.050))
1438 {
1439 yError() << "FATAL: embObjMotionControl::init() had an error while calling setcheckRemoteValue() for joint config fisico #" << fisico << "in "<< getBoardInfo();
1440 return false;
1441 }
1442 else
1443 {
1444 if(behFlags.verbosewhenok)
1445 {
1446 yDebug() << "embObjMotionControl::init() correctly configured joint config fisico #" << fisico << "in "<< getBoardInfo();
1447 }
1448 }
1449 }
1450
1451
1453 // invia la configurazione dei MOTORI //
1455
1456
1457 for(int logico=0; logico<_njoints; logico++)
1458 {
1459 int fisico = _axisMap[logico];
1460
1461 protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, fisico, eoprot_tag_mc_motor_config);
1462 eOmc_motor_config_t motor_cfg = {0};
1463 motor_cfg.maxvelocityofmotor = 0;//_maxMotorVelocity[logico]; //unused yet!
1464 motor_cfg.currentLimits.nominalCurrent = _currentLimits[logico].nominalCurrent;
1465 motor_cfg.currentLimits.overloadCurrent = _currentLimits[logico].overloadCurrent;
1466 motor_cfg.currentLimits.peakCurrent = _currentLimits[logico].peakCurrent;
1467 motor_cfg.gearbox_M2J = _gearbox_M2J[logico];
1468 motor_cfg.rotorEncoderResolution = _motorEncs[logico].resolution;
1469 motor_cfg.rotEncTolerance = _motorEncs[logico].tolerance;
1470 motor_cfg.hasHallSensor = _foc_based_info[logico].hasHallSensor;
1471 motor_cfg.hasRotorEncoder = _foc_based_info[logico].hasRotorEncoder;
1472 motor_cfg.hasTempSensor = _foc_based_info[logico].hasTempSensor;
1473 motor_cfg.hasRotorEncoderIndex = _foc_based_info[logico].hasRotorEncoderIndex;
1474 motor_cfg.hasSpeedEncoder = _foc_based_info[logico].hasSpeedEncoder;
1475 motor_cfg.verbose = _foc_based_info[logico].verbose;
1476 motor_cfg.motorPoles = _foc_based_info[logico].motorPoles;
1477 motor_cfg.rotorIndexOffset = _foc_based_info[logico].rotorIndexOffset;
1478 motor_cfg.rotorEncoderType = _motorEncs[logico].type;
1479 motor_cfg.pwmLimit =_rotorsLimits[logico].pwmMax;
1480 motor_cfg.temperatureLimit = (eOmeas_temperature_t) S_16(_temperatureSensorsVector.at(logico)->convertTempCelsiusToRaw(_temperatureLimits.at(logico).hardwareTemperatureLimit)); //passing raw value not in degree
1481 motor_cfg.limitsofrotor.max = (eOmeas_position_t) S_32(_measureConverter->posA2E(_rotorsLimits[logico].posMax, fisico ));
1482 motor_cfg.limitsofrotor.min = (eOmeas_position_t) S_32(_measureConverter->posA2E(_rotorsLimits[logico].posMin, fisico ));
1483
1484 motor_cfg.LuGre_params.Km = _lugre_params[logico].Km;
1485 motor_cfg.LuGre_params.Kw = _lugre_params[logico].Kw;
1486 motor_cfg.LuGre_params.S0 = _lugre_params[logico].S0;
1487 motor_cfg.LuGre_params.S1 = _lugre_params[logico].S1;
1488 motor_cfg.LuGre_params.Vth = _lugre_params[logico].Vth;
1489 motor_cfg.LuGre_params.Fc_pos = _lugre_params[logico].Fc_pos;
1490 motor_cfg.LuGre_params.Fc_neg = _lugre_params[logico].Fc_neg;
1491 motor_cfg.LuGre_params.Fs_pos = _lugre_params[logico].Fs_pos;
1492 motor_cfg.LuGre_params.Fs_neg = _lugre_params[logico].Fs_neg;
1493
1494 yarp::dev::Pid tmp;
1495 tmp = _measureConverter->convert_pid_to_machine(yarp::dev::VOCAB_PIDTYPE_CURRENT, _cur_pids[logico].pid, fisico);
1496 copyPid_iCub2eo(&tmp, &motor_cfg.pidcurrent);
1497
1498 tmp = _measureConverter->convert_pid_to_machine(yarp::dev::VOCAB_PIDTYPE_VELOCITY, _spd_pids[logico].pid, fisico);
1499 copyPid_iCub2eo(&tmp, &motor_cfg.pidspeed);
1500
1501 if (false == res->setcheckRemoteValue(protid, &motor_cfg, 10, 0.010, 0.050))
1502 {
1503 yError() << "FATAL: embObjMotionControl::init() had an error while calling setcheckRemoteValue() for motor config fisico #" << fisico << "in "<< getBoardInfo();
1504 return false;
1505 }
1506 else
1507 {
1508 if (behFlags.verbosewhenok)
1509 {
1510 yDebug() << "embObjMotionControl::init() correctly configured motor config fisico #" << fisico << "in "<< getBoardInfo();
1511 }
1512 }
1513 }
1514
1516 // invia la configurazione del controller //
1518
1519 protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_controller, 0, eoprot_tag_mc_controller_config);
1520
1521 eOmc_controller_config_t controller_cfg = {0};
1522 memset(&controller_cfg, 0, sizeof(eOmc_controller_config_t));
1523 controller_cfg.durationofctrlloop = (uint32_t)bdata.settings.txconfig.cycletime;
1524 controller_cfg.enableskiprecalibration = _maintenanceModeCfg.enableSkipRecalibration;
1525
1526 if(false == res->setcheckRemoteValue(protid, &controller_cfg, 10, 0.010, 0.050))
1527 {
1528 yError() << "FATAL: embObjMotionControl::init() had an error while calling setcheckRemoteValue() for the controller " << "in "<< getBoardInfo();
1529 return false;
1530 }
1531 else
1532 {
1533 if(behFlags.verbosewhenok)
1534 {
1535 yDebug() << "embObjMotionControl::init() correctly configured controller config " << "in "<< getBoardInfo();
1536 }
1537 }
1538
1540 // intialize the map of the rawValuesVectors //
1542 const char* tag = eoprot_TAG2string(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_status_addinfo_multienc);
1543
1544 _rawValuesMetadataMap.insert({{tag, rawValuesKeyMetadata({}, _njoints * eOmc_joint_multienc_maxnum)}});
1545 for (auto &[k, v] : _rawValuesMetadataMap)
1546 {
1547 std::string auxstring = "";
1548
1549 for (int i = 0; i < _njoints; i++)
1550 {
1551 getEntityName(i, auxstring);
1552 if (k == tag)
1553 {
1554 v.rawValueNames.insert(v.rawValueNames.end(),
1555 {auxstring+"_primary_encoder_raw_value",
1556 auxstring+"_secondary_encoder_raw_value",
1557 auxstring+"_primary_encoder_diagnostic"}
1558 );
1559 }
1560 auxstring.clear();
1561 }
1562 }
1563 yTrace() << "embObjMotionControl::init(): correctly instantiated for " << getBoardInfo();
1564 return true;
1565}
1566
1567
1568
1570{
1571 yTrace() << " embObjMotionControl::close()";
1572
1573 ImplementControlMode::uninitialize();
1574 ImplementEncodersTimed::uninitialize();
1575 ImplementMotorEncoders::uninitialize();
1576 ImplementPositionControl::uninitialize();
1577 ImplementVelocityControl::uninitialize();
1578 ImplementPidControl::uninitialize();
1579 ImplementControlCalibration::uninitialize();
1580 ImplementAmplifierControl::uninitialize();
1581 ImplementImpedanceControl::uninitialize();
1582 ImplementControlLimits::uninitialize();
1583 ImplementTorqueControl::uninitialize();
1584 ImplementPositionDirect::uninitialize();
1585 ImplementInteractionMode::uninitialize();
1586 ImplementRemoteVariables::uninitialize();
1587 ImplementAxisInfo::uninitialize();
1588 ImplementCurrentControl::uninitialize();
1589 ImplementPWMControl::uninitialize();
1590 ImplementJointFault::uninitialize();
1591
1592 if (_measureConverter) {delete _measureConverter; _measureConverter=0;}
1593
1594
1595 if(eomn_serv_diagn_mode_MC_AMOyarp == mcdiagnostics.config.mode)
1596 {
1597 // close the ports
1598 for(size_t i=0; i<mcdiagnostics.ports.size(); i++)
1599 {
1600 mcdiagnostics.ports[i]->close();
1601 delete mcdiagnostics.ports[i];
1602 }
1603 mcdiagnostics.ports.clear();
1604
1605 mcdiagnostics.config.mode = eomn_serv_diagn_mode_NONE;
1606 mcdiagnostics.config.par16 = 0;
1607 }
1608
1609 delete event_downsampler;
1610 // in cleanup, at date of 23feb2016 there is a call to ethManager->releaseResource() which ...
1611 // send to config all the boards and stops tx and rx treads.
1612 // thus, in here we cannot call serviceStop(mc) because there will be tx/rx activity only for the first call of ::close().
1613 // i termporarily put serviceStop(eomn_serv_category_all) inside releaseResource()
1614 // todo: later on: clear regulars of mc, stop(mc), inside releaseresource() DO NOT stop tx/rx activity and DO NOT stop all services
1615 // res->serviceStop(eomn_serv_category_mc);
1616 // #warning TODO: clear the regulars imposed by motion-control.
1617
1618 cleanup();
1619
1620 return true;
1621}
1622
1623void embObjMotionControl::cleanup(void)
1624{
1625 if(ethManager == NULL) return;
1626
1627 int ret = ethManager->releaseResource2(res, this);
1628 res = NULL;
1629 if(ret == -1)
1630 ethManager->killYourself();
1631}
1632
1633
1639
1640bool embObjMotionControl::update(eOprotID32_t id32, double timestamp, void *rxdata)
1641{
1642 // use this function to update the values cached in the class using data received by the remote boards via the network callbacks
1643 // in embObjMotionControl it is updated only the timestamp of the encoders, thuus i dont used rxdata
1644 size_t joint = eoprot_ID2index(id32);
1645 eOprotEntity_t ent = eoprot_ID2entity(id32);
1646 eOprotTag_t tag = eoprot_ID2tag(id32);
1647
1648 // rxdata = rxdata;
1649
1650 // marco.accame: pay attention using rxdata. the rxdata depends on the id32.
1651 // now the function update() is called with rxdata of different types.
1652 // if the tag is eoprot_tag_mc_joint_status, then rxdata is of type eOmc_joint_status_t*
1653 // if the tag is eoprot_tag_mc_joint_status_basic, then rxdata is of type eOmc_joint_status_basic_t*
1654
1655
1656 // for the case of id32 which contains an encoder value .... we refresh the timestamp of that encoder
1657
1658 if(true == initialised())
1659 { // do it only if we already have opened the device
1660 std::lock_guard<std::mutex> lck(_mutex);
1661 _encodersStamp[joint] = timestamp;
1662 }
1663
1664
1665 if(eomn_serv_diagn_mode_MC_AMOyarp == mcdiagnostics.config.mode)
1666 {
1667 char str[128] = "boh";
1668
1669 eoprot_ID2information(id32, str, sizeof(str));
1670
1671 if((eoprot_entity_mc_joint == ent) && (eoprot_tag_mc_joint_status_debug == tag) && (joint < mcdiagnostics.ports.size()))
1672 {
1673
1674 eOprotID32_t id32sc = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, joint, eoprot_tag_mc_joint_status_core);
1675 eOmc_joint_status_core_t jcore = {};
1676
1677 res->getLocalValue(id32sc, &jcore);
1678
1679 int32_t *debug32 = reinterpret_cast<int32_t*>(rxdata);
1680 // write into relevant port
1681
1682 Bottle& output = mcdiagnostics.ports[joint]->prepare();
1683 output.clear();
1684 //output.addString("[yt, amo, reg, pos]"); // but we must get the joint and the motor as well
1685 output.addString("[yt, amo, reg, pos]");
1686 output.addFloat64(timestamp);
1687 output.addInt32(debug32[0]);
1688 output.addInt32(debug32[1]);
1689 output.addInt32(jcore.measures.meas_position);
1690 mcdiagnostics.ports[joint]->write();
1691 }
1692 }
1693
1694 if((eoprot_entity_mc_motor == ent) && (eoprot_tag_mc_motor_status == tag))
1695 {
1696 if(false == initialised())
1697 return true;
1698
1699 uint8_t motor = eoprot_ID2index(id32);
1700 if((_temperatureSensorsVector.at(motor)->getType() == motor_temperature_sensor_none))
1701 return true;
1702
1703 eOmc_motor_status_t *mc_motor_status = reinterpret_cast<eOmc_motor_status_t*>(rxdata);
1704
1705 if((double)mc_motor_status->basic.mot_temperature < 0 ) //I get a invalid value
1706 {
1707 if(! _temperatureSensorErrorWatchdog.at(motor).isStarted())
1708 {
1709 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";
1710 _temperatureSensorErrorWatchdog.at(motor).start();
1711 }
1712 else
1713 {
1714 _temperatureSensorErrorWatchdog.at(motor).increment();
1715 if( _temperatureSensorErrorWatchdog.at(motor).isExpired())
1716 {
1717 yWarning()<< getBoardInfo() << "Motor" << motor << "failed to read" << _temperatureSensorErrorWatchdog.at(motor).getCount() << "temperature readings for" << yarp::os::Time::now() - _temperatureSensorErrorWatchdog.at(motor).getStartTime() << "seconds";
1718 _temperatureSensorErrorWatchdog.at(motor).start();
1719 }
1720 }
1721 return true;
1722 }
1723
1724 //if I'm here I have a valid value
1725 double delta_tmp = 0;
1726 double tmp = _temperatureSensorsVector.at(motor)->convertRawToTempCelsius((double)mc_motor_status->basic.mot_temperature);
1727
1728 // check if this is a spike or not
1729 // evaluate difference between current and previous temperature
1730 if(!_temperatureSpikesFilter.at(motor).isStarted()) //Pre-set of the filter buffer is ready
1731 {
1732 _temperatureSpikesFilter.at(motor).start(tmp);
1733 return true;
1734 }
1735
1736 // when i'm here the filter is ready.
1737 delta_tmp = std::abs(tmp - _temperatureSpikesFilter.at(motor).getPrevTemperature());
1738
1739 //1. check if I have a good value (not a spike)
1740 if(delta_tmp > _temperatureSpikesFilter.at(motor).getTemperatureThreshold())
1741 {
1742 //it is a spike
1743 return true;
1744 }
1745 // this is a not spike --> can update prev temperature
1746 _temperatureSpikesFilter.at(motor).updatePrevTemperature(tmp);
1747
1748 //2. tmp is good and check the limits
1749 if(tmp > _temperatureLimits[motor].warningTemperatureLimit)
1750 {
1751 if(! _temperatureExceededLimitWatchdog.at(motor).isStarted())
1752 {
1753 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";
1754 _temperatureExceededLimitWatchdog.at(motor).start();
1755 }
1756 else
1757 {
1758 if(_temperatureExceededLimitWatchdog.at(motor).isExpired())
1759 {
1760 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";
1761 _temperatureExceededLimitWatchdog.at(motor).start();
1762 }
1763 _temperatureExceededLimitWatchdog.at(motor).increment();
1764 }
1765 }
1766 else
1767 {
1768 _temperatureExceededLimitWatchdog.at(motor).clear();
1769 }
1770 }
1771 return true;
1772}
1773
1774
1775bool embObjMotionControl::getEntityName(uint32_t entityId, std::string &entityName)
1776{
1777 bool ret = getAxisNameRaw(entityId, entityName);
1778
1779 //since getAxisNameRaw set "ERROR" in entityName when an error occurred,
1780 //while this function has to return an empty string, I reset the entityName string
1781 if(!ret)
1782 {
1783 entityName.clear();
1784 }
1785 return ret;
1786
1787}
1788
1789
1790bool embObjMotionControl::getEncoderTypeName(uint32_t jomoId, eOmc_position_t pos, std::string &encoderTypeName)
1791{
1792 encoderTypeName.clear();
1793
1794 if ((jomoId >= 0) && (jomoId < _njoints))
1795 {
1796 switch (pos)
1797 {
1798 case eomc_pos_atjoint:
1799 encoderTypeName = eomc_encoder2string(_jointEncs[jomoId].type, eobool_true);
1800 break;
1801 case eomc_pos_atmotor:
1802 encoderTypeName = eomc_encoder2string(_motorEncs[jomoId].type, eobool_true);
1803 break;
1804 case eomc_pos_unknown:
1805 encoderTypeName = "UNKNOWN";
1806 break;
1807 case eomc_pos_none:
1808 default:
1809 encoderTypeName = "NONE";
1810 break;
1811 }
1812 return true;
1813 }
1814 else
1815 {
1816 encoderTypeName = "ERROR";
1817 return false;
1818 }
1819}
1820
1822bool embObjMotionControl::setPidRaw(const PidControlTypeEnum& pidtype, int j, const Pid &pid)
1823{
1824 switch (pidtype)
1825 {
1826 case VOCAB_PIDTYPE_POSITION:
1827 helper_setPosPidRaw(j,pid);
1828 break;
1829 case VOCAB_PIDTYPE_VELOCITY:
1830 //helper_setVelPidRaw(j,pid);
1831 helper_setSpdPidRaw(j, pid);
1832 break;
1833 case VOCAB_PIDTYPE_TORQUE:
1834 helper_setTrqPidRaw(j, pid);
1835 break;
1836 case VOCAB_PIDTYPE_CURRENT:
1837 helper_setCurPidRaw(j,pid);
1838 break;
1839 default:
1840 yError()<<"Invalid pidtype:"<<pidtype;
1841 break;
1842 }
1843 return true;
1844}
1845
1846bool embObjMotionControl::getPidRaw(const PidControlTypeEnum& pidtype, int axis, Pid *pid)
1847{
1848 switch (pidtype)
1849 {
1850 case VOCAB_PIDTYPE_POSITION:
1851 helper_getPosPidRaw(axis,pid);
1852 break;
1853 case VOCAB_PIDTYPE_VELOCITY:
1854 //helper_getVelPidRaw(axis,pid);
1855 helper_getSpdPidRaw(axis, pid);
1856 break;
1857 case VOCAB_PIDTYPE_TORQUE:
1858 helper_getTrqPidRaw(axis, pid);
1859 break;
1860 case VOCAB_PIDTYPE_CURRENT:
1861 helper_getCurPidRaw(axis,pid);
1862 break;
1863 default:
1864 yError()<<"Invalid pidtype:"<<pidtype;
1865 break;
1866 }
1867 return true;
1868}
1869
1870bool embObjMotionControl::helper_setPosPidRaw(int j, const Pid &pid)
1871{
1872 eOprotID32_t protoId = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_pidtrajectory);
1873 eOmc_PID_t outPid;
1874 Pid hwPid = pid;
1875
1876 //printf("helper_setPosPid: kp=%f ki=%f kd=%f\n", hwPid.kp, hwPid.ki, hwPid.kd);
1877 copyPid_iCub2eo(&hwPid, &outPid);
1878
1879 if(false == res->setRemoteValue(protoId, &outPid))
1880 {
1881 yError() << "while setting position PIDs for " << getBoardInfo() << " joint " << j;
1882 return false;
1883 }
1884
1885 return true;
1886}
1887
1888bool embObjMotionControl::setPidsRaw(const PidControlTypeEnum& pidtype, const Pid *pids)
1889{
1890 bool ret = true;
1891 for(int j=0; j< _njoints; j++)
1892 {
1893 ret &= setPidRaw(pidtype, j, pids[j]);
1894 }
1895 return ret;
1896}
1897
1898bool embObjMotionControl::setPidReferenceRaw(const PidControlTypeEnum& pidtype, int j, double ref)
1899{
1900 return NOT_YET_IMPLEMENTED("setPidReferenceRaw");
1901}
1902
1903bool embObjMotionControl::setPidReferencesRaw(const PidControlTypeEnum& pidtype, const double *refs)
1904{
1905 bool ret = true;
1906 for(int j=0, index=0; j< _njoints; j++, index++)
1907 {
1908 ret &= setPidReferenceRaw(pidtype, j, refs[index]);
1909 }
1910 return ret;
1911}
1912
1913bool embObjMotionControl::setPidErrorLimitRaw(const PidControlTypeEnum& pidtype, int j, double limit)
1914{
1915 // print_debug(AC_trace_file, "embObjMotionControl::setErrorLimitRaw()");
1916 return NOT_YET_IMPLEMENTED("setErrorLimitRaw");
1917}
1918
1919bool embObjMotionControl::setPidErrorLimitsRaw(const PidControlTypeEnum& pidtype, const double *limits)
1920{
1921 // print_debug(AC_trace_file, "embObjMotionControl::setErrorLimitsRaw()");
1922 return NOT_YET_IMPLEMENTED("setErrorLimitsRaw");
1923}
1924
1925bool embObjMotionControl::getPidErrorRaw(const PidControlTypeEnum& pidtype, int j, double *err)
1926{
1927 uint16_t size = 0;
1928 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
1929 eOmc_joint_status_core_t jcore = {0};
1930 *err = 0;
1931 if(!res->getLocalValue(id32, &jcore))
1932 return false;
1933
1934 switch(pidtype)
1935 {
1936 case VOCAB_PIDTYPE_POSITION:
1937 {
1938 if((eomc_controlmode_torque == jcore.modes.controlmodestatus) ||
1939 (eomc_controlmode_openloop == jcore.modes.controlmodestatus) ||
1940 (eomc_controlmode_current == jcore.modes.controlmodestatus))
1941 return true;
1942 else
1943 *err = (double) jcore.ofpid.generic.error1;
1944 }
1945 break;
1946 /*
1947 case VOCAB_PIDTYPE_DIRECT:
1948 {
1949 *err=0; //not yet implemented
1950 NOT_YET_IMPLEMENTED("getPidErrorRaw VOCAB_PIDTYPE_DIRECT");
1951 }
1952 break;
1953 */
1954 case VOCAB_PIDTYPE_TORQUE:
1955 {
1956 if ((eOmc_interactionmode_compliant == jcore.modes.interactionmodestatus) &&
1957 (eomc_controlmode_position == jcore.modes.controlmodestatus))
1958 {
1959 *err = (double) jcore.ofpid.complpos.errtrq;
1960 }
1961
1962 if(eomc_controlmode_torque == jcore.modes.controlmodestatus)
1963 {
1964 *err = (double) jcore.ofpid.torque.errtrq;
1965 }
1966 }
1967 break;
1968 case VOCAB_PIDTYPE_VELOCITY:
1969 {
1970 *err = 0; //not yet implemented
1971 NOT_YET_IMPLEMENTED("getPidErrorRaw VOCAB_PIDTYPE_LLSPEED");
1972 }
1973 break;
1974 case VOCAB_PIDTYPE_CURRENT:
1975 {
1976 *err = 0; //not yet implemented
1977 NOT_YET_IMPLEMENTED("getPidErrorRaw VOCAB_PIDTYPE_CURRENT");
1978 }
1979 break;
1980 default:
1981 {
1982 yError()<<"Invalid pidtype:"<<pidtype;
1983 }
1984 break;
1985 }
1986 return true;
1987}
1988
1989bool embObjMotionControl::getPidErrorsRaw(const PidControlTypeEnum& pidtype, double *errs)
1990{
1991 bool ret = true;
1992 for(int j=0; j< _njoints; j++)
1993 {
1994 ret &= getPidErrorRaw(pidtype, j, &errs[j]);
1995 }
1996 return ret;
1997}
1998
1999bool embObjMotionControl::helper_getPosPidRaw(int j, Pid *pid)
2000{
2001 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_pidtrajectory);
2002
2003 uint16_t size;
2004 eOmc_PID_t eoPID = {0};
2005
2006
2007#ifdef NETWORK_PERFORMANCE_BENCHMARK
2008 double start = yarp::os::Time::now();
2009#endif
2010
2011 bool ret = askRemoteValue(protid, &eoPID, size);
2012
2013#ifdef NETWORK_PERFORMANCE_BENCHMARK
2014 double end = yarp::os::Time::now();
2015 m_responseTimingVerifier.tick(end-start, start);
2016#endif
2017
2018 if(!ret)
2019 return false;
2020
2021 copyPid_eo2iCub(&eoPID, pid);
2022
2023 //printf("helper_getPosPid: kp=%f ki=%f kd=%f\n", pid->kp, pid->ki, pid->kd);
2024
2025 return true;
2026}
2027
2028bool embObjMotionControl::helper_getPosPidsRaw(Pid *pid)
2029{
2030 std::vector<eOmc_PID_t> eoPIDList(_njoints);
2031 bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_config_pidtrajectory, eoPIDList);
2032 if(!ret)
2033 {
2034 yError() << "failed helper_getPosPidsRaw for" << getBoardInfo();
2035 return false;
2036 }
2037
2038 for(int j=0; j<_njoints; j++)
2039 {
2040 copyPid_eo2iCub(&eoPIDList[j], &pid[j]);
2041
2042 //printf("helper_getPosPid: kp=%f ki=%f kd=%f\n", pid->kp, pid->ki, pid->kd);
2043 }
2044 return true;
2045}
2046
2047
2048bool embObjMotionControl::getPidsRaw(const PidControlTypeEnum& pidtype, Pid *pids)
2049{
2050 switch (pidtype)
2051 {
2052 case VOCAB_PIDTYPE_POSITION:
2053 helper_getPosPidsRaw(pids);
2054 break;
2055 //case VOCAB_PIDTYPE_DIRECT:
2056 // helper_getVelPidsRaw(pids);
2057 // break;
2058 case VOCAB_PIDTYPE_TORQUE:
2059 helper_getTrqPidsRaw(pids);
2060 break;
2061 case VOCAB_PIDTYPE_CURRENT:
2062 helper_getCurPidsRaw(pids);
2063 break;
2064 case VOCAB_PIDTYPE_VELOCITY:
2065 helper_getSpdPidsRaw(pids);
2066 break;
2067 default:
2068 yError()<<"Invalid pidtype:"<<pidtype;
2069 break;
2070 }
2071 return true;
2072}
2073
2074bool embObjMotionControl::getPidReferenceRaw(const PidControlTypeEnum& pidtype, int j, double *ref)
2075{
2076 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
2077 eOmc_joint_status_core_t jcore = {0};
2078 *ref = 0;
2079 if(!res->getLocalValue(id32, &jcore))
2080 return false;
2081
2082 switch (pidtype)
2083 {
2084 case VOCAB_PIDTYPE_POSITION:
2085 {
2086 if((eomc_controlmode_torque == jcore.modes.controlmodestatus) ||
2087 (eomc_controlmode_openloop == jcore.modes.controlmodestatus) ||
2088 (eomc_controlmode_current == jcore.modes.controlmodestatus))
2089 { *ref = 0; yError() << "Invalid getPidReferenceRaw() request for current control mode"; return true; }
2090 *ref = (double) jcore.ofpid.generic.reference1;
2091 }
2092 break;
2093 //case VOCAB_PIDTYPE_DIRECT:
2094 //{
2095 // *ref=0;
2096 // NOT_YET_IMPLEMENTED("getPidReferenceRaw VOCAB_PIDTYPE_DIRECT");
2097 //}
2098 //break;
2099 case VOCAB_PIDTYPE_TORQUE:
2100 {
2101 *ref = 0;
2102 NOT_YET_IMPLEMENTED("getPidReferenceRaw VOCAB_PIDTYPE_TORQUE");
2103 }
2104 break;
2105 case VOCAB_PIDTYPE_CURRENT:
2106 {
2107 *ref=0;
2108 NOT_YET_IMPLEMENTED("getPidReferenceRaw VOCAB_PIDTYPE_CURRENT");
2109 }
2110 break;
2111 case VOCAB_PIDTYPE_VELOCITY:
2112 {
2113 *ref = 0;
2114 NOT_YET_IMPLEMENTED("getPidReferenceRaw VOCAB_PIDTYPE_VELOCITY");
2115 }
2116 break;
2117 default:
2118 {
2119 *ref=0;
2120 yError()<<"Invalid pidtype:"<<pidtype;
2121 }
2122 break;
2123 }
2124 return true;
2125}
2126
2127bool embObjMotionControl::getPidReferencesRaw(const PidControlTypeEnum& pidtype, double *refs)
2128{
2129 bool ret = true;
2130
2131 // just one joint at time, wait answer before getting to the next.
2132 // This is because otherwise too many msg will be placed into can queue
2133 for(int j=0; j< _njoints; j++)
2134 {
2135 ret &= getPidReferenceRaw(pidtype, j, &refs[j]);
2136 }
2137 return ret;
2138}
2139
2140bool embObjMotionControl::getPidErrorLimitRaw(const PidControlTypeEnum& pidtype, int j, double *limit)
2141{
2142 return NOT_YET_IMPLEMENTED("getErrorLimit");
2143}
2144
2145bool embObjMotionControl::getPidErrorLimitsRaw(const PidControlTypeEnum& pidtype, double *limits)
2146{
2147 return NOT_YET_IMPLEMENTED("getErrorLimit");
2148}
2149
2150bool embObjMotionControl::resetPidRaw(const PidControlTypeEnum& pidtype, int j)
2151{
2152 return NOT_YET_IMPLEMENTED("resetPid");
2153}
2154
2155bool embObjMotionControl::disablePidRaw(const PidControlTypeEnum& pidtype, int j)
2156{
2157 return DEPRECATED("disablePidRaw");
2158}
2159
2160bool embObjMotionControl::enablePidRaw(const PidControlTypeEnum& pidtype, int j)
2161{
2162 return DEPRECATED("enablePidRaw");
2163}
2164
2165bool embObjMotionControl::setPidOffsetRaw(const PidControlTypeEnum& pidtype, int j, double v)
2166{
2167 return NOT_YET_IMPLEMENTED("setOffset");
2168}
2169
2171// Velocity control interface raw //
2173
2175{
2176 int mode=0;
2177 getControlModeRaw(j, &mode);
2178 if( (mode != VOCAB_CM_VELOCITY) &&
2179 (mode != VOCAB_CM_MIXED) &&
2180 (mode != VOCAB_CM_IMPEDANCE_VEL) &&
2181 (mode != VOCAB_CM_IDLE))
2182 {
2183 if(event_downsampler->canprint())
2184 {
2185 yError() << "velocityMoveRaw: skipping command because " << getBoardInfo() << " joint " << j << " is not in VOCAB_CM_VELOCITY mode";
2186 }
2187 return true;
2188 }
2189
2190 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_setpoint);
2191
2192 _ref_command_speeds[j] = sp ; // save internally the new value of speed.
2193
2194 eOmc_setpoint_t setpoint;
2195 setpoint.type = eomc_setpoint_velocity;
2196 setpoint.to.velocity.value = (eOmeas_velocity_t) S_32(_ref_command_speeds[j]);
2197 setpoint.to.velocity.withacceleration = (eOmeas_acceleration_t) S_32(_ref_accs[j]);
2198
2199
2200 if(false == res->setRemoteValue(protid, &setpoint))
2201 {
2202 yError() << "while setting velocity mode";
2203 return false;
2204 }
2205 return true;
2206}
2207
2209{
2210 bool ret = true;
2211 eOmc_setpoint_t setpoint;
2212
2213 setpoint.type = eomc_setpoint_velocity;
2214
2215 for(int j=0; j<_njoints; j++)
2216 {
2217 ret = velocityMoveRaw(j, sp[j]) && ret;
2218 }
2219
2220 return ret;
2221}
2222
2223
2225// Calibration control interface //
2227
2228bool embObjMotionControl::setCalibrationParametersRaw(int j, const CalibrationParameters& params)
2229{
2230 yTrace() << "setCalibrationParametersRaw for " << getBoardInfo() << "joint" << j;
2231
2232 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_calibration);
2233 eOmc_calibrator_t calib;
2234 memset(&calib, 0x00, sizeof(calib));
2235 calib.type = params.type;
2236
2237 switch (calib.type)
2238 {
2239 // muove -> amp+pid, poi calib
2240 case eomc_calibration_type0_hard_stops:
2241 calib.params.type0.pwmlimit = (int16_t)S_16(params.param1);
2242 calib.params.type0.velocity = (eOmeas_velocity_t)S_32(params.param2);
2243 calib.params.type0.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2244 break;
2245
2246 // fermo
2247 case eomc_calibration_type1_abs_sens_analog:
2248 calib.params.type1.position = (int16_t)S_16(params.param1);
2249 calib.params.type1.velocity = (eOmeas_velocity_t)S_32(params.param2);
2250 calib.params.type1.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2251 break;
2252
2253 // muove
2254 case eomc_calibration_type2_hard_stops_diff:
2255 calib.params.type2.pwmlimit = (int16_t)S_16(params.param1);
2256 calib.params.type2.velocity = (eOmeas_velocity_t)S_32(params.param2);
2257 calib.params.type2.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2258 break;
2259
2260 // muove
2261 case eomc_calibration_type3_abs_sens_digital:
2262 calib.params.type3.position = (int16_t)S_16(params.param1);
2263 calib.params.type3.velocity = (eOmeas_velocity_t)S_32(params.param2);
2264 calib.params.type3.offset = (int32_t)S_32(params.param3);
2265 calib.params.type3.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2266 break;
2267
2268 // muove
2269 case eomc_calibration_type4_abs_and_incremental:
2270 calib.params.type4.position = (int16_t)S_16(params.param1);
2271 calib.params.type4.velocity = (eOmeas_velocity_t)S_32(params.param2);
2272 calib.params.type4.maxencoder = (int32_t)S_32(params.param3);
2273 calib.params.type4.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2274 break;
2275
2276 // muove
2277 case eomc_calibration_type5_hard_stops:
2278 calib.params.type5.pwmlimit = (int32_t) S_32(params.param1);
2279 calib.params.type5.final_pos = (int32_t) S_32(params.param2);
2280 calib.params.type5.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2281 break;
2282
2283 // muove
2284 case eomc_calibration_type6_mais:
2285 calib.params.type6.position = (int32_t)S_32(params.param1);
2286 calib.params.type6.velocity = (int32_t)S_32(params.param2);
2287 calib.params.type6.current = (int32_t)S_32(params.param3);
2288 calib.params.type6.vmin = (int32_t)S_32(params.param4);
2289 calib.params.type6.vmax = (int32_t)S_32(params.param5);
2290 calib.params.type6.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2291 break;
2292
2293 // muove
2294 case eomc_calibration_type7_hall_sensor:
2295 calib.params.type7.position = (int32_t)S_32(params.param1);
2296 calib.params.type7.velocity = (int32_t)S_32(params.param2);
2297 //param3 is not used
2298 calib.params.type7.vmin = (int32_t)S_32(params.param4);
2299 calib.params.type7.vmax = (int32_t)S_32(params.param5);
2300 calib.params.type7.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2301 break;
2302
2303 //muove
2304 case eomc_calibration_type8_tripod_internal_hard_stop:
2305 calib.params.type8.pwmlimit = (int32_t) S_32(params.param1);
2306 calib.params.type8.max_delta = (int32_t) S_32(params.param2);
2307 calib.params.type8.calibrationZero = (int32_t)S_32(params.paramZero /* * _angleToEncoder[j] */);
2308 break;
2309
2310 case eomc_calibration_type9_tripod_external_hard_stop:
2311 calib.params.type9.pwmlimit = (int32_t) S_32(params.param1);
2312 calib.params.type9.max_delta = (int32_t) S_32(params.param2);
2313 calib.params.type9.calibrationZero = (int32_t)S_32(params.paramZero /* * _angleToEncoder[j] */);
2314 break;
2315
2316 case eomc_calibration_type10_abs_hard_stop:
2317 calib.params.type10.pwmlimit = (int32_t) S_32(params.param1);
2318 calib.params.type10.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2319 break;
2320
2321 case eomc_calibration_type11_cer_hands:
2322 calib.params.type11.offset0 = (int32_t)S_32(params.param1);
2323 calib.params.type11.offset1 = (int32_t)S_32(params.param2);
2324 calib.params.type11.offset2 = (int32_t)S_32(params.param3);
2325 calib.params.type11.cable_range = (int32_t)S_32(params.param4);
2326 calib.params.type11.pwm = (int32_t)S_32(params.param5);
2327 //calib.params.type11.calibrationZero = 32767;//(int32_t)S_32(params.paramZero * _angleToEncoder[j]);
2328 break;
2329
2330 case eomc_calibration_type12_absolute_sensor:
2331 calib.params.type12.rawValueAtZeroPos = (int32_t)S_32(params.param1);
2332 calib.params.type12.calibrationDelta = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2333 break;
2334
2335 case eomc_calibration_type13_cer_hands_2:
2336 calib.params.type13.rawValueAtZeroPos0 = (int32_t)S_32(params.param1);
2337 calib.params.type13.rawValueAtZeroPos1 = (int32_t)S_32(params.param2);
2338 calib.params.type13.rawValueAtZeroPos2 = (int32_t)S_32(params.param3);
2339 calib.params.type13.rawValueAtZeroPos3 = (int32_t)S_32(params.param4);
2340 break;
2341
2342 case eomc_calibration_type14_qenc_hard_stop_and_fap:
2343 calib.params.type14.pwmlimit = (int32_t)S_32(params.param1);
2344 calib.params.type14.final_pos = (int32_t)S_32(params.param2);
2345 calib.params.type14.invertdirection = (uint8_t)U_32(params.param3);
2346 calib.params.type14.rotation = (int32_t)S_32(params.param4);
2347
2348 if (calib.params.type14.invertdirection != 0 && calib.params.type14.invertdirection != 1)
2349 {
2350 yError() << "Error in param3 of calibartion type 14 for joint " << j << "Admitted values are: 0=FALSE and 1=TRUE";
2351 return false;
2352 }
2353
2354
2355 if(!checkCalib14RotationParam(calib.params.type14.rotation))
2356 {
2357 yError() << "Error in param4 of calibartion type 14 for joint " << j << "Admitted values are: 0, 32768, 16384, -16384 [0, 180, 90, -90] in iCubDegree";
2358 return false;
2359 }
2360 calib.params.type14.offset = (int32_t)S_32(params.param5);
2361 calib.params.type14.calibrationZero = (int32_t)S_32(_measureConverter->posA2E(params.paramZero, j));
2362
2363 break;
2364
2365 default:
2366 yError() << "Calibration type unknown!! (embObjMotionControl)\n";
2367 return false;
2368 break;
2369 }
2370
2371 if (false == res->setRemoteValue(protid, &calib))
2372 {
2373 yError() << "while setting velocity mode";
2374 return false;
2375 }
2376
2377 _calibrated[j] = true;
2378
2379 return true;
2380}
2381
2382bool embObjMotionControl::checkCalib14RotationParam(int32_t calib_param4)
2383{
2384 eOmc_calib14_ROT_t urotation = eomc_int2calib14_ROT(calib_param4);
2385
2386 if (urotation == eOmc_calib14_ROT_zero ||
2387 urotation == eOmc_calib14_ROT_plus180 ||
2388 urotation == eOmc_calib14_ROT_plus090 ||
2389 urotation == eOmc_calib14_ROT_minus090)
2390 {
2391 return true;
2392 }
2393
2394 return false;
2395}
2396
2397bool embObjMotionControl::calibrateAxisWithParamsRaw(int j, unsigned int type, double p1, double p2, double p3)
2398{
2399 yTrace() << "calibrateRaw for" << getBoardInfo() << "joint" << j;
2400
2401 // Tenere il check o forzare questi sottostati?
2402// if(!_enabledAmp[j ] )
2403// {
2404// yWarning () << "Called calibrate for joint " << j << "with PWM(AMP) not enabled, forcing it!!";
2405// // return false;
2406// }
2407
2408// if(!_enabledPid[j ])
2409// {
2410// yWarning () << "Called calibrate for joint " << j << "with PID not enabled, forcing it!!";
2411// // return false;
2412// }
2413
2414 // There is no explicit command "go to calibration mode" but it is implicit in the calibration command
2415
2416
2417 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_calibration);
2418 eOmc_calibrator_t calib;
2419 memset(&calib, 0x00, sizeof(calib));
2420 calib.type = type;
2421
2422 switch(type)
2423 {
2424 // muove -> amp+pid, poi calib
2425 case eomc_calibration_type0_hard_stops:
2426 calib.params.type0.pwmlimit = (int16_t) S_16(p1);
2427 calib.params.type0.velocity = (eOmeas_velocity_t) S_32(p2);
2428 break;
2429
2430 // fermo
2431 case eomc_calibration_type1_abs_sens_analog:
2432 calib.params.type1.position = (int16_t) S_16(p1);
2433 calib.params.type1.velocity = (eOmeas_velocity_t) S_32(p2);
2434 break;
2435
2436 // muove
2437 case eomc_calibration_type2_hard_stops_diff:
2438 calib.params.type2.pwmlimit = (int16_t) S_16(p1);
2439 calib.params.type2.velocity = (eOmeas_velocity_t) S_32(p2);
2440 break;
2441
2442 // muove
2443 case eomc_calibration_type3_abs_sens_digital:
2444 calib.params.type3.position = (int16_t) S_16(p1);
2445 calib.params.type3.velocity = (eOmeas_velocity_t) S_32(p2);
2446 calib.params.type3.offset = (int32_t) S_32(p3);
2447 break;
2448
2449 // muove
2450 case eomc_calibration_type4_abs_and_incremental:
2451 calib.params.type4.position = (int16_t) S_16(p1);
2452 calib.params.type4.velocity = (eOmeas_velocity_t) S_32(p2);
2453 calib.params.type4.maxencoder = (int32_t) S_32(p3);
2454 break;
2455
2456 default:
2457 yError () << "Calibration type unknown!! (embObjMotionControl)\n";
2458 return false;
2459 break;
2460 }
2461
2462 if(false == res->setRemoteValue(protid, &calib))
2463 {
2464 yError() << "while setting velocity mode";
2465 return false;
2466 }
2467
2468 _calibrated[j ] = true;
2469
2470 return true;
2471}
2472
2473
2475{
2476 bool result = false;
2477 eOmc_joint_status_core_t jcore = {0};
2478 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, axis, eoprot_tag_mc_joint_status_core);
2479 if(!res->getLocalValue(id32, &jcore))
2480 {
2481 yError () << "Failure of getLocalValue() inside embObjMotionControl::calibrationDoneRaw(axis=" << axis << ") for " << getBoardInfo();
2482 return false;
2483 }
2484
2485 eOmc_controlmode_t type = (eOmc_controlmode_t) jcore.modes.controlmodestatus;
2486
2487
2488 // if the control mode is no longer a calibration type, it means calibration ended
2489 if (eomc_controlmode_idle == type)
2490 {
2491 result = (_maintenanceModeCfg.enableSkipRecalibration) ? true : false;
2492 }
2493 else if (eomc_controlmode_calib == type)
2494 {
2495 result = false;
2496 }
2497 else if (eomc_controlmode_hwFault == type)
2498 {
2499 yError("unable to complete calibration: joint %d in 'hw_fault status' inside calibrationDoneRaw() function", axis);
2500 result = false;
2501 }
2502 else if (eomc_controlmode_notConfigured == type)
2503 {
2504 yError("unable to complete calibration: joint %d in 'not_configured' status inside calibrationDoneRaw() function", axis);
2505 result = false;
2506 }
2507 else if (eomc_controlmode_unknownError == type)
2508 {
2509 yError("unable to complete calibration: joint %d in 'unknownError' status inside calibrationDoneRaw() function", axis);
2510 result = false;
2511 }
2512 else if (eomc_controlmode_configured == type)
2513 {
2514 yError("unable to complete calibration: joint %d in 'configured' status inside calibrationDoneRaw() function", axis);
2515 result = false;
2516 }
2517 else
2518 {
2519 result = true;
2520 }
2521 return result;
2522}
2523
2525// Position control interface //
2527
2529{
2530 *ax=_njoints;
2531
2532 return true;
2533}
2534
2536{
2537 if (yarp::os::Time::now()-_last_position_move_time[j]<MAX_POSITION_MOVE_INTERVAL)
2538 {
2539 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.";
2540 }
2541 _last_position_move_time[j] = yarp::os::Time::now();
2542
2543 int mode = 0;
2544 getControlModeRaw(j, &mode);
2545 if( (mode != VOCAB_CM_POSITION) &&
2546 (mode != VOCAB_CM_MIXED) &&
2547 (mode != VOCAB_CM_IMPEDANCE_POS) &&
2548 (mode != VOCAB_CM_IDLE))
2549 {
2550 if (event_downsampler->canprint())
2551 {
2552 yError() << "positionMoveRaw: skipping command because " << getBoardInfo() << " joint " << j << " is not in VOCAB_CM_POSITION mode";
2553 }
2554 return true;
2555 }
2556
2557 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_setpoint);
2558 _ref_command_positions[j] = ref; // save internally the new value of pos.
2559
2560 eOmc_setpoint_t setpoint;
2561
2562 setpoint.type = (eOenum08_t) eomc_setpoint_position;
2563 setpoint.to.position.value = (eOmeas_position_t) S_32(_ref_command_positions[j]);
2564 setpoint.to.position.withvelocity = (eOmeas_velocity_t) S_32(_ref_speeds[j]);
2565
2566 return res->setRemoteValue(protid, &setpoint);
2567}
2568
2570{
2571 bool ret = true;
2572
2573 for(int j=0, index=0; j< _njoints; j++, index++)
2574 {
2575 ret &= positionMoveRaw(j, refs[index]);
2576 }
2577 return ret;
2578}
2579
2581{
2582 return NOT_YET_IMPLEMENTED("positionRelative");
2583}
2584
2586{
2587 return NOT_YET_IMPLEMENTED("positionRelative");
2588}
2589
2590
2592{
2593 eObool_t ismotiondone = eobool_false;
2594 uint16_t size = 0;
2595
2596 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core_modes_ismotiondone);
2597 if(false == askRemoteValue(id32, &ismotiondone, size))
2598 {
2599 yError () << "Failure of askRemoteValue() inside embObjMotionControl::checkMotionDoneRaw(j=" << j << ") for " << getBoardInfo();
2600 return false;
2601 }
2602
2603
2604 *flag = ismotiondone; // eObool_t can have values only amongst: eobool_true (1) or eobool_false (0).
2605
2606 return true;
2607}
2608
2610{
2611 std::vector <eObool_t> ismotiondoneList(_njoints);
2612 bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_status_core_modes_ismotiondone, ismotiondoneList);
2613 if(false == ret)
2614 {
2615 yError () << "Failure of askRemoteValues() inside embObjMotionControl::checkMotionDoneRaw for all joints of" << getBoardInfo();
2616 return false;
2617 }
2618 *flag=true;
2619 for(int j=0; j<_njoints; j++)
2620 {
2621 *flag &= ismotiondoneList[j]; // eObool_t can have values only amongst: eobool_true (1) or eobool_false (0).
2622 }
2623 return true;
2624}
2625
2627{
2628 // Velocity is expressed in iDegrees/s
2629 // save internally the new value of speed; it'll be used in the positionMove
2630 int index = j ;
2631 _ref_speeds[index] = sp;
2632 return true;
2633}
2634
2636{
2637 // Velocity is expressed in iDegrees/s
2638 // save internally the new value of speed; it'll be used in the positionMove
2639 for(int j=0, index=0; j< _njoints; j++, index++)
2640 {
2641 _ref_speeds[index] = spds[index];
2642 }
2643 return true;
2644}
2645
2647{
2648 // Acceleration is expressed in iDegrees/s^2
2649 // save internally the new value of the acceleration; it'll be used in the velocityMove command
2650
2651 if (acc > 1e6)
2652 {
2653 _ref_accs[j ] = 1e6;
2654 }
2655 else if (acc < -1e6)
2656 {
2657 _ref_accs[j ] = -1e6;
2658 }
2659 else
2660 {
2661 _ref_accs[j ] = acc;
2662 }
2663
2664 return true;
2665}
2666
2668{
2669 // Acceleration is expressed in iDegrees/s^2
2670 // save internally the new value of the acceleration; it'll be used in the velocityMove command
2671 for(int j=0, index=0; j< _njoints; j++, index++)
2672 {
2673 if (accs[j] > 1e6)
2674 {
2675 _ref_accs[index] = 1e6;
2676 }
2677 else if (accs[j] < -1e6)
2678 {
2679 _ref_accs[index] = -1e6;
2680 }
2681 else
2682 {
2683 _ref_accs[index] = accs[j];
2684 }
2685 }
2686 return true;
2687}
2688
2690{
2691 if (j<0 || j>_njoints) return false;
2692#if ASK_REFERENCE_TO_FIRMWARE
2693 *spd = _ref_speeds[j];
2694 //return NOT_YET_IMPLEMENTED("getRefSpeedRaw");
2695#else
2696 *spd = _ref_speeds[j];
2697#endif
2698 return true;
2699}
2700
2702{
2703 memcpy(spds, _ref_speeds, sizeof(double) * _njoints);
2704 return true;
2705}
2706
2708{
2709 *acc = _ref_accs[j];
2710 return true;
2711}
2712
2714{
2715 memcpy(accs, _ref_accs, sizeof(double) * _njoints);
2716 return true;
2717}
2718
2720{
2721 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_stoptrajectory);
2722
2723 eObool_t stop = eobool_true;
2724
2725 return res->setRemoteValue(protid, &stop);
2726}
2727
2729{
2730 bool ret = true;
2731 for(int j=0; j< _njoints; j++)
2732 {
2733 ret &= stopRaw(j);
2734 }
2735 return ret;
2736}
2738
2740// Position control2 interface //
2742
2743bool embObjMotionControl::positionMoveRaw(const int n_joint, const int *joints, const double *refs)
2744{
2745 bool ret = true;
2746 for(int j=0; j<n_joint; j++)
2747 {
2748 ret = ret &&positionMoveRaw(joints[j], refs[j]);
2749 }
2750 return ret;
2751}
2752
2753bool embObjMotionControl::relativeMoveRaw(const int n_joint, const int *joints, const double *deltas)
2754{
2755 bool ret = true;
2756 for(int j=0; j<n_joint; j++)
2757 {
2758 ret = ret &&relativeMoveRaw(joints[j], deltas[j]);
2759 }
2760 return ret;
2761}
2762
2763bool embObjMotionControl::checkMotionDoneRaw(const int n_joint, const int *joints, bool *flag)
2764{
2765
2766 //1) first of all, check if all joints number are ok
2767 for(int j=0; j<n_joint; j++)
2768 {
2769 if(joints[j] >= _njoints)
2770 {
2771 yError() << getBoardInfo() << ":checkMotionDoneRaw required for not existing joint ( " << joints[j] << ")";
2772 return false;
2773 }
2774 }
2775
2776 //2) ask check motion done for all my joints
2777 std::vector <eObool_t> ismotiondoneList(_njoints);
2778 bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_status_core_modes_ismotiondone, ismotiondoneList);
2779 if(false == ret)
2780 {
2781 yError () << getBoardInfo() << "Failure of askRemoteValues() inside embObjMotionControl::checkMotionDoneRaw for a group of joint"; getBoardInfo();
2782 return false;
2783 }
2784
2785 //3) verify only the given joints
2786 bool tot_val = true;
2787 for(int j=0; j<n_joint; j++)
2788 {
2789 tot_val &= ismotiondoneList[joints[j]];
2790 }
2791
2792 *flag = tot_val;
2793 return true;
2794
2795}
2796
2797bool embObjMotionControl::setRefSpeedsRaw(const int n_joint, const int *joints, const double *spds)
2798{
2799 bool ret = true;
2800 for(int j=0; j<n_joint; j++)
2801 {
2802 ret = ret &&setRefSpeedRaw(joints[j], spds[j]);
2803 }
2804 return ret;
2805}
2806
2807bool embObjMotionControl::setRefAccelerationsRaw(const int n_joint, const int *joints, const double *accs)
2808{
2809 bool ret = true;
2810 for(int j=0; j<n_joint; j++)
2811 {
2812 ret = ret &&setRefAccelerationRaw(joints[j], accs[j]);
2813 }
2814 return ret;
2815}
2816
2817bool embObjMotionControl::getRefSpeedsRaw(const int n_joint, const int *joints, double *spds)
2818{
2819 bool ret = true;
2820 for(int j=0; j<n_joint; j++)
2821 {
2822 ret = ret && getRefSpeedRaw(joints[j], &spds[j]);
2823 }
2824 return ret;
2825}
2826
2827bool embObjMotionControl::getRefAccelerationsRaw(const int n_joint, const int *joints, double *accs)
2828{
2829 bool ret = true;
2830 for(int j=0; j<n_joint; j++)
2831 {
2832 ret = ret && getRefAccelerationRaw(joints[j], &accs[j]);
2833 }
2834 return ret;
2835}
2836
2837bool embObjMotionControl::stopRaw(const int n_joint, const int *joints)
2838{
2839 bool ret = true;
2840 for(int j=0; j<n_joint; j++)
2841 {
2842 ret = ret &&stopRaw(joints[j]);
2843 }
2844 return ret;
2845}
2846
2848
2849// ControlMode
2850
2852{
2853 eOmc_joint_status_core_t jcore = {0};
2854 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
2855 if(! res->getLocalValue(protid, &jcore))
2856 return false;
2857
2858 eOmc_controlmode_t type = (eOmc_controlmode_t) jcore.modes.controlmodestatus;
2859
2861 return true;
2862}
2863
2864// IControl Mode 2
2866{
2867 bool ret = true;
2868 for(int j=0; j< _njoints; j++)
2869 {
2870 ret = ret && getControlModeRaw(j, &v[j]);
2871 }
2872 return ret;
2873}
2874
2875bool embObjMotionControl::getControlModesRaw(const int n_joint, const int *joints, int *modes)
2876{
2877 bool ret = true;
2878 for(int j=0; j< n_joint; j++)
2879 {
2880 ret = ret && getControlModeRaw(joints[j], &modes[j]);
2881 }
2882 return ret;
2883}
2884
2885
2886
2887// marco.accame: con alberto cardellino abbiamo parlato della correttezza di effettuare la verifica di quanto imposto (in setControlModeRaw() ed affini)
2888// andando a rileggere il valore nella scheda eth fino a che esso non sia quello atteso. si deve fare oppure no?
2889// con il control mode il can ora lo fa ma e' giusto? era cosi' anche in passato?
2890bool embObjMotionControl::setControlModeRaw(const int j, const int _mode)
2891{
2892 bool ret = true;
2893 eOenum08_t controlmodecommand = 0;
2894
2895 if((_mode == VOCAB_CM_TORQUE) && (_trq_pids[j].enabled == false))
2896 {
2897 yError()<<"Torque control is disabled. Check your configuration parameters";
2898 return false;
2899 }
2900
2901 if(!controlModeCommandConvert_yarp2embObj(_mode, controlmodecommand) )
2902 {
2903 yError() << "SetControlMode: received unknown control mode for " << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(_mode);
2904 return false;
2905 }
2906
2907 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_controlmode);
2908 if(false == res->setRemoteValue(protid, &controlmodecommand) )
2909 {
2910 yError() << "setControlModeRaw failed for " << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(_mode);
2911 return false;
2912 }
2913
2914
2915 ret = checkRemoteControlModeStatus(j, _mode);
2916
2917 if(false == ret)
2918 {
2919 yError() << "In embObjMotionControl::setControlModeRaw(j=" << j << ", mode=" << yarp::os::Vocab32::decode(_mode).c_str() << ") for " << getBoardInfo() << " has failed checkRemoteControlModeStatus()";
2920 }
2921
2922 return ret;
2923}
2924
2925
2926bool embObjMotionControl::setControlModesRaw(const int n_joint, const int *joints, int *modes)
2927{
2928 bool ret = true;
2929 eOenum08_t controlmodecommand = 0;
2930
2931
2932 for(int i=0; i<n_joint; i++)
2933 {
2934 if ((modes[i] == VOCAB_CM_TORQUE) && (_trq_pids[i].enabled == false)) {yError()<<"Torque control is disabled. Check your configuration parameters"; continue;}
2935
2936 if(!controlModeCommandConvert_yarp2embObj(modes[i], controlmodecommand) )
2937 {
2938 yError() << "SetControlModesRaw(): received unknown control mode for " << getBoardInfo() << " joint " << joints[i] << " mode " << Vocab32::decode(modes[i]);
2939
2940 return false;
2941 }
2942
2943 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, joints[i], eoprot_tag_mc_joint_cmmnds_controlmode);
2944 if(false == res->setRemoteValue(protid, &controlmodecommand) )
2945 {
2946 yError() << "setControlModesRaw() could not send set<cmmnds_controlmode> for " << getBoardInfo() << " joint " << joints[i] << " mode " << Vocab32::decode(modes[i]);
2947
2948 return false;
2949 }
2950
2951 bool tmpresult = checkRemoteControlModeStatus(joints[i], modes[i]);
2952 if(false == tmpresult)
2953 {
2954 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]);
2955 }
2956
2957 ret = ret && tmpresult;
2958
2959 }
2960
2961 return ret;
2962}
2963
2965{
2966 bool ret = true;
2967 eOenum08_t controlmodecommand = 0;
2968
2969 for(int i=0; i<_njoints; i++)
2970 {
2971
2972 if ((modes[i] == VOCAB_CM_TORQUE) && (_trq_pids[i].enabled == false))
2973 {
2974 yError()<<"Torque control is disabled. Check your configuration parameters";
2975 continue;
2976 }
2977
2978 if(!controlModeCommandConvert_yarp2embObj(modes[i], controlmodecommand) )
2979 {
2980 yError() << "SetControlMode: received unknown control mode for" << getBoardInfo() << " joint " << i << " mode " << Vocab32::decode(modes[i]);
2981 return false;
2982 }
2983
2984 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, i, eoprot_tag_mc_joint_cmmnds_controlmode);
2985 if(false == res->setRemoteValue(protid, &controlmodecommand) )
2986 {
2987 yError() << "setControlModesRaw failed for " << getBoardInfo() << " joint " << i << " mode " << Vocab32::decode(modes[i]);
2988 return false;
2989 }
2990
2991 bool tmpresult = checkRemoteControlModeStatus(i, modes[i]);
2992 if(false == tmpresult)
2993 {
2994 yError() << "setControlModesRaw(int *modes) could not check with checkRemoteControlModeStatus() for" << getBoardInfo() << " joint " << i << " mode " << Vocab32::decode(modes[i]);
2995 }
2996
2997 ret = ret && tmpresult;
2998
2999 }
3000
3001
3002 return ret;
3003}
3004
3005
3007
3009{
3010 return NOT_YET_IMPLEMENTED("setEncoder");
3011}
3012
3014{
3015 return NOT_YET_IMPLEMENTED("setEncoders");
3016}
3017
3019{
3020 return NOT_YET_IMPLEMENTED("resetEncoder");
3021}
3022
3024{
3025 return NOT_YET_IMPLEMENTED("resetEncoders");
3026}
3027
3028bool embObjMotionControl::getEncoderRaw(int j, double *value)
3029{
3030 eOmc_joint_status_core_t core;
3031 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
3032
3033 bool ret = res->getLocalValue(protid, &core);
3034
3035 if(ret)
3036 {
3037 *value = (double) core.measures.meas_position;
3038 }
3039 else
3040 {
3041 yError() << "embObjMotionControl while reading encoder";
3042 *value = 0;
3043 }
3044
3045 return ret;
3046}
3047
3049{
3050 bool ret = true;
3051 for(int j=0; j< _njoints; j++)
3052 {
3053 ret &= getEncoderRaw(j, &encs[j]);
3054
3055 }
3056 return ret;
3057}
3058
3060{
3061 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
3062 eOmc_joint_status_core_t core;
3063 *sp = 0;
3064 if(!res->getLocalValue(protid, &core))
3065 {
3066 return false;
3067 }
3068 // extract requested data from status
3069 *sp = (double) core.measures.meas_velocity;
3070 return true;
3071}
3072
3074{
3075 bool ret = true;
3076 for(int j=0; j< _njoints; j++)
3077 {
3078 ret &= getEncoderSpeedRaw(j, &spds[j]);
3079 }
3080 return ret;
3081}
3082
3084{
3085 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
3086 eOmc_joint_status_core_t core;
3087 *acc = 0;
3088 if(! res->getLocalValue(protid, &core))
3089 {
3090 return false;
3091 }
3092 *acc = (double) core.measures.meas_acceleration;
3093 return true;
3094}
3095
3097{
3098 bool ret = true;
3099 for(int j=0; j< _njoints; j++)
3100 {
3101 ret &= getEncoderAccelerationRaw(j, &accs[j]);
3102 }
3103 return ret;
3104}
3105
3107
3108bool embObjMotionControl::getEncodersTimedRaw(double *encs, double *stamps)
3109{
3110 bool ret = getEncodersRaw(encs);
3111 std::lock_guard<std::mutex> lck(_mutex);
3112 for(int i=0; i<_njoints; i++)
3113 stamps[i] = _encodersStamp[i];
3114 return ret;
3115}
3116
3117bool embObjMotionControl::getEncoderTimedRaw(int j, double *encs, double *stamp)
3118{
3119 bool ret = getEncoderRaw(j, encs);
3120 std::lock_guard<std::mutex> lck(_mutex);
3121 *stamp = _encodersStamp[j];
3122 return ret;
3123}
3124
3126
3128{
3129 *num=_njoints;
3130 return true;
3131}
3132
3133bool embObjMotionControl::setMotorEncoderRaw(int m, const double val)
3134{
3135 return NOT_YET_IMPLEMENTED("setMotorEncoder");
3136}
3137
3139{
3140 return NOT_YET_IMPLEMENTED("setMotorEncoders");
3141}
3142
3144{
3145 return NOT_YET_IMPLEMENTED("setMotorEncoderCountsPerRevolutionRaw");
3146}
3147
3149{
3150 return NOT_YET_IMPLEMENTED("getMotorEncoderCountsPerRevolutionRaw");
3151}
3152
3154{
3155 return NOT_YET_IMPLEMENTED("resetMotorEncoder");
3156}
3157
3159{
3160 return NOT_YET_IMPLEMENTED("reseMotortEncoders");
3161}
3162
3164{
3165 eOmc_motor_status_basic_t status;
3166 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_status_basic);
3167
3168 bool ret = res->getLocalValue(protid, &status);
3169 if(ret)
3170 {
3171 *value = (double) status.mot_position;
3172 }
3173 else
3174 {
3175 yError() << "embObjMotionControl while reading motor encoder position";
3176 *value = 0;
3177 }
3178
3179 return ret;
3180}
3181
3183{
3184 bool ret = true;
3185 for(int j=0; j< _njoints; j++)
3186 {
3187 ret &= getMotorEncoderRaw(j, &encs[j]);
3188
3189 }
3190 return ret;
3191}
3192
3194{
3195 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_status_basic);
3196 eOmc_motor_status_basic_t tmpMotorStatus;
3197 bool ret = res->getLocalValue(protid, &tmpMotorStatus);
3198 if(ret)
3199 {
3200 *sp = (double) tmpMotorStatus.mot_velocity;
3201 }
3202 else
3203 {
3204 yError() << "embObjMotionControl while reading motor encoder speed";
3205 *sp = 0;
3206 }
3207 return true;
3208}
3209
3211{
3212 bool ret = true;
3213 for(int j=0; j< _njoints; j++)
3214 {
3215 ret &= getMotorEncoderSpeedRaw(j, &spds[j]);
3216 }
3217 return ret;
3218}
3219
3221{
3222 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_status_basic);
3223 eOmc_motor_status_basic_t tmpMotorStatus;
3224 bool ret = res->getLocalValue(protid, &tmpMotorStatus);
3225 if(ret)
3226 {
3227 *acc = (double) tmpMotorStatus.mot_acceleration;
3228 }
3229 else
3230 {
3231 yError() << "embObjMotionControl while reading motor encoder acceleration";
3232 *acc = 0;
3233 }
3234 return true;
3235}
3236
3238{
3239 bool ret = true;
3240 for(int j=0; j< _njoints; j++)
3241 {
3242 ret &= getMotorEncoderAccelerationRaw(j, &accs[j]);
3243 }
3244 return ret;
3245}
3246
3247bool embObjMotionControl::getMotorEncodersTimedRaw(double *encs, double *stamps)
3248{
3249 bool ret = getMotorEncodersRaw(encs);
3250 std::lock_guard<std::mutex> lck(_mutex);
3251 for(int i=0; i<_njoints; i++)
3252 stamps[i] = _encodersStamp[i];
3253 return ret;
3254}
3255
3256bool embObjMotionControl::getMotorEncoderTimedRaw(int m, double *encs, double *stamp)
3257{
3258 bool ret = getMotorEncoderRaw(m, encs);
3259 std::lock_guard<std::mutex> lck(_mutex);
3260 *stamp = _encodersStamp[m];
3261 return ret;
3262}
3264
3266
3268{
3269 return DEPRECATED("enableAmpRaw");
3270}
3271
3273{
3274 return DEPRECATED("disableAmpRaw");
3275}
3276
3277bool embObjMotionControl::getCurrentRaw(int j, double *value)
3278{
3279 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_status_basic);
3280 eOmc_motor_status_basic_t tmpMotorStatus;
3281 bool ret = res->getLocalValue(protid, &tmpMotorStatus);
3282
3283 *value = (double) tmpMotorStatus.mot_current;
3284 return true;
3285}
3286
3288{
3289 bool ret = true;
3290 for(int j=0; j< _njoints; j++)
3291 {
3292 ret &= getCurrentRaw(j, &vals[j]);
3293 }
3294 return ret;
3295}
3296
3298{
3299 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config_currentlimits);
3300 uint16_t size;
3301 eOmc_current_limits_params_t currentlimits = {0};
3302
3303 if(!askRemoteValue(protid, &currentlimits, size))
3304 {
3305 yError() << "embObjMotionControl::setMaxCurrentRaw() could not read max current for " << getBoardInfo() << "joint " << j;
3306 return false;
3307 }
3308
3309 //set current overload
3310 currentlimits.overloadCurrent = (eOmeas_current_t) S_16(val);
3311
3312 //send new values
3313 return res->setRemoteValue(protid, &currentlimits);
3314}
3315
3317{
3318 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config_currentlimits);
3319 uint16_t size;
3320 eOmc_current_limits_params_t currentlimits = {0};
3321 *val = 0;
3322
3323 if(!askRemoteValue(protid, &currentlimits, size))
3324 {
3325 yError() << "embObjMotionControl::getMaxCurrentRaw() could not read max current for " << getBoardInfo() << "joint " << j;
3326 return false;
3327 }
3328
3329 *val = (double) currentlimits.overloadCurrent;
3330
3331 return true;
3332}
3333
3335{
3336 //VALE: can i set this func like deprecated? none sets _enabledAmp!!
3337 (_enabledAmp[j ]) ? *st = 1 : *st = 0;
3338 return true;
3339}
3340
3342{
3343 bool ret = true;
3344 for(int j=0; j<_njoints; j++)
3345 {
3346 sts[j] = _enabledAmp[j];
3347 }
3348
3349 return ret;
3350}
3351
3352#ifdef IMPLEMENT_DEBUG_INTERFACE
3353//----------------------------------------------\\
3354// Debug interface
3355//----------------------------------------------\\
3356
3357bool embObjMotionControl::setParameterRaw(int j, unsigned int type, double value) { return NOT_YET_IMPLEMENTED("setParameterRaw"); }
3358bool embObjMotionControl::getParameterRaw(int j, unsigned int type, double* value) { return NOT_YET_IMPLEMENTED("getParameterRaw"); }
3359bool embObjMotionControl::getDebugParameterRaw(int j, unsigned int index, double* value) { return NOT_YET_IMPLEMENTED("getDebugParameterRaw"); }
3360bool embObjMotionControl::setDebugParameterRaw(int j, unsigned int index, double value) { return NOT_YET_IMPLEMENTED("setDebugParameterRaw"); }
3361bool embObjMotionControl::setDebugReferencePositionRaw(int j, double value) { return NOT_YET_IMPLEMENTED("setDebugReferencePositionRaw"); }
3362bool embObjMotionControl::getDebugReferencePositionRaw(int j, double* value) { return NOT_YET_IMPLEMENTED("getDebugReferencePositionRaw");}
3363
3364#endif //IMPLEMENT_DEBUG_INTERFACE
3365
3366// Limit interface
3367bool embObjMotionControl::setLimitsRaw(int j, double min, double max)
3368{
3369 bool ret = true;
3370 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_userlimits);
3371
3372 eOmeas_position_limits_t limits;
3373 limits.max = (eOmeas_position_t) S_32(max);
3374 limits.min = (eOmeas_position_t) S_32(min);
3375
3376 ret = res->setRemoteValue(protid, &limits);
3377
3378
3379 if(!ret)
3380 {
3381 yError() << "while setting position limits for joint" << j << " \n";
3382 }
3383 return ret;
3384}
3385
3386bool embObjMotionControl::getLimitsRaw(int j, double *min, double *max)
3387{
3388 eOmeas_position_limits_t limits;
3389 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_userlimits);
3390 uint16_t size;
3391
3392 if(! askRemoteValue(protoid, &limits, size))
3393 return false;
3394
3395 *min = (double)limits.min + SAFETY_THRESHOLD;
3396 *max = (double)limits.max - SAFETY_THRESHOLD;
3397 return true;
3398}
3399
3401{
3402 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3403 uint16_t size;
3404 eOmc_motor_config_t motor_cfg;
3405 if(! askRemoteValue(protoid, &motor_cfg, size))
3406 return false;
3407
3408 // refresh cached value when reading data from the EMS
3409 *gearbox = (double)motor_cfg.gearbox_M2J;
3410
3411 return true;
3412}
3413
3414bool embObjMotionControl::getRotorLimitsRaw(int j, double *rotorMin, double *rotorMax)
3415{
3416 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3417 uint16_t size;
3418 eOmc_motor_config_t motor_cfg;
3419 if(! askRemoteValue(protoid, &motor_cfg, size))
3420 return false;
3421 *rotorMax = (double)( motor_cfg.limitsofrotor.max);
3422 *rotorMin = (double)( motor_cfg.limitsofrotor.min);
3423 return true;
3424}
3425
3427{
3428 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config);
3429 uint16_t size;
3430 eOmc_joint_config_t joint_cfg;
3431 if(! askRemoteValue(protoid, &joint_cfg, size))
3432 return false;
3433
3434 // refresh cached value when reading data from the EMS
3435 type = (int)joint_cfg.tcfiltertype;
3436 return true;
3437}
3438
3440{
3441 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3442 uint16_t size;
3443 eOmc_motor_config_t motor_cfg;
3444 if(! askRemoteValue(protoid, &motor_cfg, size))
3445 return false;
3446
3447 // refresh cached value when reading data from the EMS
3448 rotres = (double)motor_cfg.rotorEncoderResolution;
3449
3450 return true;
3451}
3452
3454{
3455 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config);
3456 uint16_t size;
3457 eOmc_joint_config_t joint_cfg;
3458 if(! askRemoteValue(protoid, &joint_cfg, size))
3459 return false;
3460
3461 // refresh cached value when reading data from the EMS
3462 jntres = (double)joint_cfg.jntEncoderResolution;
3463
3464 return true;
3465}
3466
3468{
3469 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config);
3470 uint16_t size;
3471 eOmc_joint_config_t joint_cfg;
3472 if(! askRemoteValue(protoid, &joint_cfg, size))
3473 return false;
3474
3475 // refresh cached value when reading data from the EMS
3476 type = (int)joint_cfg.jntEncoderType;
3477
3478 return true;
3479}
3480
3482{
3483 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3484 uint16_t size;
3485 eOmc_motor_config_t motor_cfg;
3486 if(! askRemoteValue(protoid, &motor_cfg, size))
3487 return false;
3488
3489 // refresh cached value when reading data from the EMS
3490 type = (int)motor_cfg.rotorEncoderType;
3491
3492 return true;
3493}
3494
3496{
3497 yError("getKinematicMJRaw not yet implemented");
3498 return false;
3499}
3500
3502{
3503 // refresh cached value when reading data from the EMS
3504 ret = "NONE";
3505 if (_temperatureSensorsVector.at(j)->getType() == motor_temperature_sensor_pt100)
3506 {
3507 ret = "PT100";
3508 }
3509 else if (_temperatureSensorsVector.at(j)->getType() == motor_temperature_sensor_pt1000)
3510 {
3511 ret = "PT1000";
3512 }
3513 else
3514 {
3515 ret = "NONE";
3516 }
3517
3518 return true;
3519}
3520
3522{
3523 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3524 uint16_t size;
3525 eOmc_motor_config_t motor_cfg;
3526 if(! askRemoteValue(protoid, &motor_cfg, size))
3527 return false;
3528
3529 // refresh cached value when reading data from the EMS
3530 ret = (int)motor_cfg.hasTempSensor;
3531
3532 return true;
3533}
3534
3536{
3537 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3538 uint16_t size;
3539 eOmc_motor_config_t motor_cfg;
3540 if(! askRemoteValue(protoid, &motor_cfg, size))
3541 return false;
3542
3543 // refresh cached value when reading data from the EMS
3544 ret = (int)motor_cfg.hasHallSensor;
3545
3546 return true;
3547}
3548
3550{
3551 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3552 uint16_t size;
3553 eOmc_motor_config_t motor_cfg;
3554 if(! askRemoteValue(protoid, &motor_cfg, size))
3555 return false;
3556
3557 // refresh cached value when reading data from the EMS
3558 ret = (int)motor_cfg.hasRotorEncoder;
3559
3560 return true;
3561}
3562
3564{
3565 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3566 uint16_t size;
3567 eOmc_motor_config_t motor_cfg;
3568 if(! askRemoteValue(protoid, &motor_cfg, size))
3569 return false;
3570
3571 // refresh cached value when reading data from the EMS
3572 ret = (int)motor_cfg.hasRotorEncoderIndex;
3573
3574 return true;
3575}
3576
3578{
3579 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3580
3581 uint16_t size;
3582 eOmc_motor_config_t motor_cfg;
3583 if(! askRemoteValue(protoid, &motor_cfg, size))
3584 return false;
3585
3586 // refresh cached value when reading data from the EMS
3587 poles = (int)motor_cfg.motorPoles;
3588
3589 return true;
3590}
3591
3592bool embObjMotionControl::getRotorIndexOffsetRaw(int j, double& rotorOffset)
3593{
3594 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
3595 uint16_t size;
3596 eOmc_motor_config_t motor_cfg;
3597 if(! askRemoteValue(protoid, &motor_cfg, size))
3598 return false;
3599
3600 // refresh cached value when reading data from the EMS
3601 rotorOffset = (double)motor_cfg.rotorIndexOffset;
3602
3603 return true;
3604}
3605
3606bool embObjMotionControl::getAxisNameRaw(int axis, std::string& name)
3607{
3608 if (axis >= 0 && axis < _njoints)
3609 {
3610 name = _axesInfo[axis].name;
3611 return true;
3612 }
3613 else
3614 {
3615 name = "ERROR";
3616 return false;
3617 }
3618}
3619
3620bool embObjMotionControl::getJointTypeRaw(int axis, yarp::dev::JointTypeEnum& type)
3621{
3622 if (axis >= 0 && axis < _njoints)
3623 {
3624 type = _axesInfo[axis].type;
3625 return true;
3626 }
3627 else
3628 {
3629 return false;
3630 }
3631}
3632
3633bool embObjMotionControl::getJointDeadZoneRaw(int j, double &jntDeadZone)
3634{
3635 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config);
3636 uint16_t size;
3637 eOmc_joint_config_t joint_cfg;
3638 if(! askRemoteValue(protoid, &joint_cfg, size))
3639 return false;
3640
3641 // refresh cached value when reading data from the EMS
3642 jntDeadZone = _measureConverter->posE2A((double)joint_cfg.deadzone, _axisMap[j]);
3643
3644 return true;
3645}
3646
3647// IRemoteVariables
3648bool embObjMotionControl::getRemoteVariableRaw(std::string key, yarp::os::Bottle& val)
3649{
3650 val.clear();
3651 if (key == "kinematic_mj")
3652 {
3653 // Return the reduced kinematic_mj matrix considering only the joints actually exposed to the user
3654 Bottle& ret = val.addList();
3655
3656 eOmn_serv_type_t mc_serv_type = (eOmn_serv_type_t)serviceConfig.ethservice.configuration.type;
3657 if(iNeedCouplingsInfo())
3658 {
3659 for (int r=0; r<_njoints; r++)
3660 {
3661 for (int c = 0; c < _njoints; c++)
3662 {
3663 // matrixJ2M is stored as row major in the eomc_couplingInfo_t,
3664 // and kinematic_mj is returned as a row major serialization as well
3665 ret.addFloat64(_couplingInfo.matrixJ2M[4 * r + c]);
3666 }
3667 }
3668 }
3669 else
3670 {
3671 ret.addFloat64(0.0);
3672 }
3673 return true;
3674 }
3675 else if (key == "encoders")
3676 {
3677 Bottle& r = val.addList(); for (int i = 0; i < _njoints; i++) { r.addFloat64(_measureConverter->posA2E(1.0, i)); }
3678 return true;
3679 }
3680 else if (key == "rotorEncoderResolution")
3681 {
3682 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getRotorEncoderResolutionRaw(i, tmp); r.addFloat64(tmp); }
3683 return true;
3684 }
3685 else if (key == "jointEncoderResolution")
3686 {
3687 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getJointEncoderResolutionRaw(i, tmp); r.addFloat64(tmp); }
3688 return true;
3689 }
3690 else if (key == "gearbox_M2J")
3691 {
3692 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp=0; getGearboxRatioRaw(i, &tmp); r.addFloat64(tmp); }
3693 return true;
3694 }
3695 else if (key == "gearbox_E2J")
3696 {
3697 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp=0; getGerabox_E2J(i, &tmp); r.addFloat64(tmp); }
3698 return true;
3699 }
3700 else if (key == "hasHallSensor")
3701 {
3702 Bottle& r = val.addList(); for (int i = 0; i < _njoints; i++) { int tmp = 0; getHasHallSensorRaw(i, tmp); r.addInt32(tmp); }
3703 return true;
3704 }
3705 else if (key == "hasTempSensor")
3706 {
3707 Bottle& r = val.addList(); for (int i = 0; i < _njoints; i++) { int tmp = 0; getHasTempSensorsRaw(i, tmp); r.addInt32(tmp); }
3708 return true;
3709 }
3710 else if (key == "TemperatureSensorType")
3711 {
3712 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { std::string tmp = ""; getTemperatureSensorTypeRaw(i, tmp); r.addString(tmp); }
3713 return true;
3714 }
3715 else if (key == "hasRotorEncoder")
3716 {
3717 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { int tmp = 0; getHasRotorEncoderRaw(i, tmp); r.addInt32(tmp); }
3718 return true;
3719 }
3720 else if (key == "hasRotorEncoderIndex")
3721 {
3722 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { int tmp = 0; getHasRotorEncoderIndexRaw(i, tmp); r.addInt32(tmp); }
3723 return true;
3724 }
3725 else if (key == "rotorIndexOffset")
3726 {
3727 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getRotorIndexOffsetRaw(i, tmp); r.addFloat64(tmp); }
3728 return true;
3729 }
3730 else if (key == "motorPoles")
3731 {
3732 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { int tmp = 0; getMotorPolesRaw(i, tmp); r.addInt32(tmp); }
3733 return true;
3734 }
3735 else if (key == "pidCurrentKp")
3736 {
3737 Bottle& r = val.addList(); for (int i = 0; i < _njoints; i++) { Pid p; getPidRaw(PidControlTypeEnum::VOCAB_PIDTYPE_CURRENT, i, &p); r.addFloat64(p.kp); }
3738 return true;
3739 }
3740 else if (key == "pidCurrentKi")
3741 {
3742 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { Pid p; getPidRaw(PidControlTypeEnum::VOCAB_PIDTYPE_CURRENT, i, &p); r.addFloat64(p.ki); }
3743 return true;
3744 }
3745 else if (key == "pidCurrentShift")
3746 {
3747 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { Pid p; getPidRaw(PidControlTypeEnum::VOCAB_PIDTYPE_CURRENT, i, &p); r.addFloat64(p.scale); }
3748 return true;
3749 }
3750 else if (key == "pidCurrentOutput")
3751 {
3752 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); }
3753 return true;
3754 }
3755 else if (key == "jointEncoderType")
3756 {
3757 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++)
3758 {
3759 int t; string s;
3760 getJointEncoderTypeRaw(i, t); uint8_t tt = t; bool b = EncoderType_eo2iCub(&tt, &s);
3761 if (b == false)
3762 {
3763 yError("Invalid jointEncoderType");
3764 }
3765 r.addString(s);
3766 }
3767 return true;
3768 }
3769 else if (key == "rotorEncoderType")
3770 {
3771 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++)
3772 {
3773 int t; string s;
3774 getRotorEncoderTypeRaw(i, t); uint8_t tt = t; bool b = EncoderType_eo2iCub(&tt, &s);
3775 if (b == false)
3776 {
3777 yError("Invalid motorEncoderType");
3778 }
3779 r.addString(s);
3780 }
3781 return true;
3782 }
3783 else if (key == "coulombThreshold")
3784 {
3785 val.addString("not implemented yet");
3786 return true;
3787 }
3788 else if (key == "torqueControlFilterType")
3789 {
3790 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { int t; getTorqueControlFilterType(i, t); r.addFloat64(t); }
3791 return true;
3792 }
3793 else if (key == "torqueControlEnabled")
3794 {
3795
3796 Bottle& r = val.addList();
3797 for(int i = 0; i<_njoints; i++)
3798 {
3799 r.addInt32((int)_trq_pids[i].enabled );
3800 }
3801 return true;
3802 }
3803 else if (key == "PWMLimit")
3804 {
3805 Bottle& r = val.addList(); for (int i = 0; i< _njoints; i++) { double tmp = 0; getPWMLimitRaw(i, &tmp); r.addFloat64(tmp); }
3806 return true;
3807 }
3808 else if (key == "motOverloadCurr")
3809 {
3810 Bottle& r = val.addList(); for (int i = 0; i< _njoints; i++) { double tmp = 0; getMaxCurrentRaw(i, &tmp); r.addFloat64(tmp); }
3811 return true;
3812 }
3813 else if (key == "motNominalCurr")
3814 {
3815 Bottle& r = val.addList(); for (int i = 0; i< _njoints; i++) { double tmp = 0; getNominalCurrentRaw(i, &tmp); r.addFloat64(tmp); }
3816 return true;
3817 }
3818 else if (key == "motPeakCurr")
3819 {
3820 Bottle& r = val.addList(); for (int i = 0; i< _njoints; i++) { double tmp = 0; getPeakCurrentRaw(i, &tmp); r.addFloat64(tmp); }
3821 return true;
3822 }
3823 else if (key == "PowerSuppVoltage")
3824 {
3825 Bottle& r = val.addList(); for (int i = 0; i< _njoints; i++) { double tmp = 0; getPowerSupplyVoltageRaw(i, &tmp); r.addFloat64(tmp); }
3826 return true;
3827 }
3828 else if (key == "rotorMax")
3829 {
3830 double tmp1, tmp2;
3831 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getRotorLimitsRaw(i, &tmp1, &tmp2); r.addFloat64(tmp2); }
3832 return true;
3833 }
3834 else if (key == "rotorMin")
3835 {
3836 double tmp1, tmp2;
3837 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getRotorLimitsRaw(i, &tmp1, &tmp2); r.addFloat64(tmp1); }
3838 return true;
3839 }
3840 else if (key == "jointMax")
3841 {
3842 double tmp1, tmp2;
3843 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getLimitsRaw(i, &tmp1, &tmp2); r.addFloat64(tmp2); }
3844 return true;
3845 }
3846 else if (key == "jointMin")
3847 {
3848 double tmp1, tmp2;
3849 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getLimitsRaw(i, &tmp1, &tmp2); r.addFloat64(tmp1); }
3850 return true;
3851 }
3852 else if (key == "jointEncTolerance")
3853 {
3854 double tmp1;
3855 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getJointEncTolerance(i, &tmp1); r.addFloat64(tmp1); }
3856 return true;
3857 }
3858 else if (key == "motorEncTolerance")
3859 {
3860 double tmp1;
3861 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getMotorEncTolerance(i, &tmp1); r.addFloat64(tmp1); }
3862 return true;
3863 }
3864 else if (key == "jointDeadZone")
3865 {
3866 double tmp1;
3867 Bottle& r = val.addList(); for (int i = 0; i<_njoints; i++) { double tmp = 0; getJointDeadZoneRaw(i, tmp1); r.addFloat64(tmp1); }
3868 return true;
3869 }
3870 else if (key == "readonly_position_PIDraw")
3871 {
3872 Bottle& r = val.addList();
3873 for (int i = 0; i < _njoints; i++)
3874 { Pid p;
3875 getPidRaw(PidControlTypeEnum::VOCAB_PIDTYPE_POSITION, i, &p);
3876 char buff[1000];
3877 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);
3878 r.addString(buff);
3879 }
3880 return true;
3881 }
3882 else if (key == "readonly_velocity_PIDraw")
3883 {
3884 Bottle& r = val.addList();
3885 for (int i = 0; i < _njoints; i++)
3886 { Pid p; getPidRaw(PidControlTypeEnum::VOCAB_PIDTYPE_VELOCITY, i, &p);
3887 char buff[1000];
3888 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);
3889 r.addString(buff);
3890 }
3891 return true;
3892 }
3893 else if (key == "readonly_torque_PIDraw")
3894 {
3895 Bottle& r = val.addList();
3896 for (int i = 0; i < _njoints; i++)
3897 { Pid p; getPidRaw(PidControlTypeEnum::VOCAB_PIDTYPE_TORQUE, i, &p);
3898 char buff[1000];
3899 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);
3900 r.addString(buff);
3901 }
3902 return true;
3903 }
3904 else if (key == "readonly_current_PIDraw")
3905 {
3906 Bottle& r = val.addList();
3907 for (int i = 0; i < _njoints; i++)
3908 { Pid p; getPidRaw(PidControlTypeEnum::VOCAB_PIDTYPE_CURRENT, i, &p);
3909 char buff[1000];
3910 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);
3911 r.addString(buff);
3912 }
3913 return true;
3914 }
3915 else if (key == "readonly_llspeed_PIDraw")
3916 {
3917 Bottle& r = val.addList();
3918 for (int i = 0; i < _njoints; i++)
3919 {
3920 Pid p; getPidRaw(PidControlTypeEnum::VOCAB_PIDTYPE_VELOCITY, i, &p);
3921 char buff[1000];
3922 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);
3923 r.addString(buff);
3924 }
3925 return true;
3926 }
3927 else if (key == "readonly_motor_torque_params_raw")
3928 {
3929 Bottle& r = val.addList();
3930 for (int i = 0; i < _njoints; i++)
3931 {
3932 MotorTorqueParameters params;
3933 getMotorTorqueParamsRaw(i, &params);
3934 char buff[1000];
3935 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);
3936 r.addString(buff);
3937 }
3938 return true;
3939 }
3940 yWarning("getRemoteVariable(): Unknown variable %s", key.c_str());
3941 return false;
3942}
3943
3944bool embObjMotionControl::setRemoteVariableRaw(std::string key, const yarp::os::Bottle& val)
3945{
3946 string s1 = val.toString();
3947 if (val.size() != _njoints)
3948 {
3949 yWarning("setRemoteVariable(): Protocol error %s", s1.c_str());
3950 return false;
3951 }
3952
3953 if (key == "kinematic_mj")
3954 {
3955 yWarning("setRemoteVariable(): Impossible to set kinematic_mj parameter at runtime.");
3956 return false;
3957 }
3958// else if (key == "rotor")
3959// {
3960// 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
3961// return true;
3962// }
3963// else if (key == "gearbox_M2J")
3964// {
3965// 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
3966// return true;
3967// }
3968 else if (key == "PWMLimit")
3969 {
3970 for (int i = 0; i < _njoints; i++) setPWMLimitRaw(i, val.get(i).asFloat64());
3971 return true;
3972 }
3973 //disabled for used safety
3974#if 0
3975 else if (key == "jointMax")
3976 {
3977 double min, max;
3978 for (int i = 0; i < _njoints; i++)
3979 {
3980 getLimitsRaw(i, &min, &max);
3981 setLimitsRaw(i, min, val.get(i).asFloat64());
3982 }
3983 return true;
3984 }
3985 else if (key == "jointMin")
3986 {
3987 double min, max;
3988 for (int i = 0; i < _njoints; i++)
3989 {
3990 getLimitsRaw(i, &min, &max);
3991 setLimitsRaw(i, val.get(i).asFloat64(), max);
3992 }
3993 }
3994#endif
3995 yWarning("setRemoteVariable(): Unknown variable %s", key.c_str());
3996 return false;
3997}
3998
3999bool embObjMotionControl::getRemoteVariablesListRaw(yarp::os::Bottle* listOfKeys)
4000{
4001 listOfKeys->clear();
4002 listOfKeys->addString("kinematic_mj");
4003 listOfKeys->addString("encoders");
4004 listOfKeys->addString("gearbox_M2J");
4005 listOfKeys->addString("gearbox_E2J");
4006 listOfKeys->addString("hasHallSensor");
4007 listOfKeys->addString("hasTempSensor");
4008 listOfKeys->addString("TemperatureSensorType");
4009 listOfKeys->addString("hasRotorEncoder");
4010 listOfKeys->addString("hasRotorEncoderIndex");
4011 listOfKeys->addString("rotorIndexOffset");
4012 listOfKeys->addString("rotorEncoderResolution");
4013 listOfKeys->addString("jointEncoderResolution");
4014 listOfKeys->addString("motorPoles");
4015 listOfKeys->addString("pidCurrentKp");
4016 listOfKeys->addString("pidCurrentKi");
4017 listOfKeys->addString("pidCurrentShift");
4018 listOfKeys->addString("pidCurrentOutput");
4019 listOfKeys->addString("coulombThreshold");
4020 listOfKeys->addString("torqueControlFilterType");
4021 listOfKeys->addString("jointEncoderType");
4022 listOfKeys->addString("rotorEncoderType");
4023 listOfKeys->addString("PWMLimit");
4024 listOfKeys->addString("motOverloadCurr");
4025 listOfKeys->addString("motNominalCurr");
4026 listOfKeys->addString("motPeakCurr");
4027 listOfKeys->addString("PowerSuppVoltage");
4028 listOfKeys->addString("rotorMax");
4029 listOfKeys->addString("rotorMin");
4030 listOfKeys->addString("jointMax");
4031 listOfKeys->addString("jointMin");
4032 listOfKeys->addString("jointEncTolerance");
4033 listOfKeys->addString("motorEncTolerance");
4034 listOfKeys->addString("jointDeadZone");
4035 listOfKeys->addString("readonly_position_PIDraw");
4036 listOfKeys->addString("readonly_velocity_PIDraw");
4037 listOfKeys->addString("readonly_current_PIDraw");
4038 listOfKeys->addString("readonly_torque_PIDraw");
4039 listOfKeys->addString("readonly_motor_torque_params_raw");
4040 return true;
4041}
4042
4043// IControlLimits2
4044bool embObjMotionControl::setVelLimitsRaw(int axis, double min, double max)
4045{
4046 return NOT_YET_IMPLEMENTED("setVelLimitsRaw");
4047}
4048
4049bool embObjMotionControl::getVelLimitsRaw(int axis, double *min, double *max)
4050{
4051 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, axis, eoprot_tag_mc_joint_config);
4052 uint16_t size;
4053 eOmc_joint_config_t joint_cfg;
4054 if(! askRemoteValue(protoid, &joint_cfg, size))
4055 return false;
4056
4057 *max = joint_cfg.maxvelocityofjoint;
4058 *min = 0;
4059
4060 return true;
4061}
4062
4063
4064/*
4065 * IVirtualAnalogSensor Interface
4066 *
4067 * DEPRECATED!! WILL BE REMOVED IN THE NEAR FUTURE!!
4068 *
4069 */
4070
4072{
4073 return VAS_status::VAS_OK;
4074};
4075
4077{
4078 return _njoints;
4079};
4080
4082{
4083 bool ret = true;
4084
4085 for(int j=0; j< _njoints; j++)
4086 {
4087 ret = ret && updateVirtualAnalogSensorMeasure(j, fTorques[j]);
4088 }
4089 return ret;
4090}
4091
4092bool embObjMotionControl::updateVirtualAnalogSensorMeasure(int userLevel_jointNumber, double &fTorque)
4093{
4094 int j = _axisMap[userLevel_jointNumber];
4095
4096 eOmeas_torque_t meas_torque = 0;
4097 static double curr_time = Time::now();
4098 static int count_saturation=0;
4099
4100 meas_torque = (eOmeas_torque_t) S_32(_measureConverter->trqN2S(fTorque, j));
4101
4102 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_inputs_externallymeasuredtorque);
4103// We don't need anymore to cache locally because ems board broadcast its torque value in joint status core
4104// // i write also locally because i want to read it back later on inside getTorqueRaw()
4105// res->setLocalValue(protoid, &meas_torque);
4106
4107 // and i want also to send it to the board
4108 return res->setRemoteValue(protoid, &meas_torque);
4109}
4110
4111// end IVirtualAnalogSensor //
4112
4113
4114// Torque control
4116{
4117 eOmc_joint_status_core_t jstatus;
4118 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
4119 bool ret = res->getLocalValue(protoid, &jstatus);
4120 *t = (double) _measureConverter->trqS2N(jstatus.measures.meas_torque, j);
4121 return ret;
4122}
4123
4125{
4126 bool ret = true;
4127 for(int j=0; j<_njoints; j++)
4128 ret = ret && getTorqueRaw(j, &t[j]);
4129 return true;
4130}
4131
4132bool embObjMotionControl::getTorqueRangeRaw(int j, double *min, double *max)
4133{
4134 return NOT_YET_IMPLEMENTED("getTorqueRangeRaw");
4135}
4136
4137bool embObjMotionControl::getTorqueRangesRaw(double *min, double *max)
4138{
4139 return NOT_YET_IMPLEMENTED("getTorqueRangesRaw");
4140}
4141
4143{
4144 bool ret = true;
4145 for(int j=0; j<_njoints && ret; j++)
4146 ret &= setRefTorqueRaw(j, t[j]);
4147 return ret;
4148}
4149
4151{
4152 eOmc_setpoint_t setpoint;
4153 setpoint.type = (eOenum08_t) eomc_setpoint_torque;
4154 setpoint.to.torque.value = (eOmeas_torque_t) S_32(t);
4155
4156 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_setpoint);
4157 return res->setRemoteValue(protid, &setpoint);
4158}
4159
4160bool embObjMotionControl::setRefTorquesRaw(const int n_joint, const int *joints, const double *t)
4161{
4162 bool ret = true;
4163 for(int j=0; j< n_joint; j++)
4164 {
4165 ret &= setRefTorqueRaw(joints[j], t[j]);
4166 }
4167 return ret;
4168}
4169
4171{
4172 bool ret = true;
4173 for(int j=0; j<_njoints && ret; j++)
4174 ret &= getRefTorqueRaw(j, &t[j]);
4175 return ret;
4176}
4177
4179{
4180 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
4181 eOmc_joint_status_core_t jcore = {0};
4182 *t =0 ;
4183
4184
4185 if(!res->getLocalValue(id32, &jcore))
4186 {
4187 yError() << "embObjMotionControl::getRefTorqueRaw() could not read pid torque reference pos for " << getBoardInfo() << "joint " << j;
4188 return false;
4189 }
4190
4191 if ((eOmc_interactionmode_compliant == jcore.modes.interactionmodestatus) &&
4192 (eomc_controlmode_position == jcore.modes.controlmodestatus))
4193 {
4194 *t = (double) jcore.ofpid.complpos.reftrq;
4195 }
4196
4197 if(eomc_controlmode_torque == jcore.modes.controlmodestatus)
4198 {
4199 *t = (double) jcore.ofpid.torque.reftrq;
4200 }
4201
4202 return true;
4203}
4204
4205bool embObjMotionControl::helper_setTrqPidRaw(int j, const Pid &pid)
4206{
4207 eOmc_PID_t outPid;
4208 Pid hwPid = pid;
4209
4210 //printf("DEBUG setTorquePidRaw: %f %f %f %f %f\n",hwPid.kp , hwPid.ki, hwPid.kd , hwPid.stiction_up_val , hwPid.stiction_down_val );
4211
4212 copyPid_iCub2eo(&hwPid, &outPid);
4213 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_pidtorque);
4214 return res->setRemoteValue(protid, &outPid);
4215}
4216
4217bool embObjMotionControl::helper_getTrqPidRaw(int j, Pid *pid)
4218{
4219 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_pidtorque);
4220
4221 uint16_t size;
4222 eOmc_PID_t eoPID;
4223 if(! askRemoteValue(protoid, &eoPID, size))
4224 return false;
4225
4226 copyPid_eo2iCub(&eoPID, pid);
4227 //printf("DEBUG getTorquePidRaw: %f %f %f %f %f\n",pid->kp , pid->ki, pid->kd , pid->stiction_up_val , pid->stiction_down_val );
4228
4229 return true;
4230}
4231
4232bool embObjMotionControl::helper_getTrqPidsRaw(Pid *pid)
4233{
4234 std::vector<eOmc_PID_t> eoPIDList (_njoints);
4235 bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_config_pidtorque, eoPIDList);
4236 if(! ret)
4237 return false;
4238 for(int j=0; j< _njoints; j++)
4239 {
4240 copyPid_eo2iCub(&eoPIDList[j], &pid[j]);
4241 //printf("DEBUG getTorquePidRaw: %f %f %f %f %f\n",pid->kp , pid->ki, pid->kd , pid->stiction_up_val , pid->stiction_down_val );
4242 }
4243 return true;
4244}
4245
4246
4247bool embObjMotionControl::getImpedanceRaw(int j, double *stiffness, double *damping)
4248{
4249 // first set is done in the open function because the whole joint config is sent to the EMSs
4250 eOmc_impedance_t val;
4251
4252 if(!getWholeImpedanceRaw(j, val))
4253 return false;
4254
4255 *stiffness = (double) (val.stiffness);
4256 *damping = (double) (val.damping);
4257 return true;
4258}
4259
4260bool embObjMotionControl::getWholeImpedanceRaw(int j, eOmc_impedance_t &imped)
4261{
4262 // first set is done in the open function because the whole joint config is sent to the EMSs
4263
4264 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_impedance);
4265 uint16_t size;
4266 if(! askRemoteValue(protoid, &imped, size))
4267 return false;
4268
4269 // refresh cached value when reading data from the EMS
4270 _cacheImpedance->damping = imped.damping;
4271 _cacheImpedance->stiffness = imped.stiffness;
4272 _cacheImpedance->offset = imped.offset;
4273 return true;
4274}
4275
4276bool embObjMotionControl::setImpedanceRaw(int j, double stiffness, double damping)
4277{
4278 bool ret = true;
4279 eOmc_impedance_t val;
4280
4281 // Need to read the whole struct and modify just 2 of them -> now aching the old values and re-using them.
4282 // first set is done in the open function because the whole joint config is sent to the EMSs
4283 // cleaner solution, split the impedance structure into 2 separeted nework variables
4284// if(!getWholeImpedanceRaw(j, val))
4285// return false;
4286
4287 _cacheImpedance[j].stiffness = (eOmeas_stiffness_t) stiffness;
4288 _cacheImpedance[j].damping = (eOmeas_damping_t) damping;
4289
4290 val.stiffness = _cacheImpedance[j].stiffness;
4291 val.damping = _cacheImpedance[j].damping;
4292 val.offset = _cacheImpedance[j].offset;
4293
4294 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_impedance);
4295
4296
4297 ret &= res->setRemoteValue(protid, &val);
4298 return ret;
4299}
4300
4302{
4303 bool ret = true;
4304 eOmc_impedance_t val;
4305
4306 // first set is done in the open function because the whole joint config is sent to the EMSs
4307// if(!getWholeImpedanceRaw(j, val))
4308// return false;
4309
4310 _cacheImpedance[j].offset = (eOmeas_torque_t) S_32(offset);
4311 val.stiffness = _cacheImpedance[j].stiffness;
4312 val.damping = _cacheImpedance[j].damping;
4313 val.offset = _cacheImpedance[j].offset;
4314
4315 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_impedance);
4316
4317
4318 ret &= res->setRemoteValue(protid, &val);
4319
4320 return ret;
4321}
4322
4324{
4325 eOmc_impedance_t val;
4326
4327 if(!getWholeImpedanceRaw(j, val))
4328 return false;
4329
4330 *offset = val.offset;
4331 return true;
4332}
4333
4334bool embObjMotionControl::getCurrentImpedanceLimitRaw(int j, double *min_stiff, double *max_stiff, double *min_damp, double *max_damp)
4335{
4336 *min_stiff = _impedance_limits[j].min_stiff;
4337 *max_stiff = _impedance_limits[j].max_stiff;
4338 *min_damp = _impedance_limits[j].min_damp;
4339 *max_damp = _impedance_limits[j].max_damp;
4340 return true;
4341}
4342
4343bool embObjMotionControl::getMotorTorqueParamsRaw(int j, MotorTorqueParameters *params)
4344{
4345 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_motor_params);
4346
4347 uint16_t size;
4348 eOmc_motor_params_t eo_params = {0};
4349 if(! askRemoteValue(protoid, &eo_params, size))
4350 return false;
4351
4352 params->bemf = eo_params.bemf_value;
4353 params->bemf_scale = eo_params.bemf_scale;
4354 params->ktau = eo_params.ktau_value;
4355 params->ktau_scale = eo_params.ktau_scale;
4356 params->viscousPos = eo_params.friction.viscous_pos_val;
4357 params->viscousNeg = eo_params.friction.viscous_neg_val ;
4358 params->coulombPos = eo_params.friction.coulomb_pos_val;
4359 params->coulombNeg = eo_params.friction.coulomb_neg_val;
4360 params->velocityThres = eo_params.friction.velocityThres_val;
4361
4362 //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);
4363
4364 return true;
4365}
4366
4367bool embObjMotionControl::setMotorTorqueParamsRaw(int j, const MotorTorqueParameters params)
4368{
4369 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_motor_params);
4370 eOmc_motor_params_t eo_params = {0};
4371
4372 //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);
4373
4374 eo_params.bemf_value = (float) params.bemf;
4375 eo_params.bemf_scale = (uint8_t) params.bemf_scale;
4376 eo_params.ktau_value = (float) params.ktau;
4377 eo_params.ktau_scale = (uint8_t) params.ktau_scale;
4378 eo_params.friction.viscous_pos_val = static_cast<float32_t>(params.viscousPos);
4379 eo_params.friction.viscous_neg_val = static_cast<float32_t>(params.viscousNeg);
4380 eo_params.friction.coulomb_pos_val = static_cast<float32_t>(params.coulombPos);
4381 eo_params.friction.coulomb_neg_val = static_cast<float32_t>(params.coulombNeg);
4382 eo_params.friction.velocityThres_val = static_cast<float32_t>(params.velocityThres);
4383
4384
4385 if(false == res->setRemoteValue(id32, &eo_params))
4386 {
4387 yError() << "embObjMotionControl::setMotorTorqueParamsRaw() could not send set message for" << getBoardInfo() << "joint " << j;
4388 return false;
4389 }
4390
4391 return true;
4392}
4393
4394// IVelocityControl2
4395bool embObjMotionControl::velocityMoveRaw(const int n_joint, const int *joints, const double *spds)
4396{
4397 bool ret = true;
4398
4399 for(int j=0; j< n_joint; j++)
4400 {
4401 ret &= velocityMoveRaw(joints[j], spds[j]);
4402 }
4403 return ret;
4404}
4405
4406/*
4407bool embObjMotionControl::helper_setVelPidRaw(int j, const Pid &pid)
4408{
4409 eOprotID32_t protoId = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_piddirect);
4410 eOmc_PID_t outPid;
4411 Pid hwPid = pid;
4412
4413 if(!_dir_pids[j].enabled)
4414 {
4415 yError() << "eoMc " << getBoardInfo() << ": it is not possible set direct pid for joint " << j <<", because velocity pid is enabled in xml files";
4416 return false;
4417 }
4418
4419 copyPid_iCub2eo(&hwPid, &outPid);
4420
4421 if (false == res->setRemoteValue(protoId, &outPid))
4422 {
4423 yError() << "while setting direct PIDs for" << getBoardInfo() << " joint " << j;
4424 return false;
4425 }
4426
4427 return true;
4428
4429 //return NOT_YET_IMPLEMENTED("Our boards do not have a Velocity Pid");
4430}
4431*/
4432
4433bool embObjMotionControl::helper_getVelPidRaw(int j, Pid *pid)
4434{
4435 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_config_piddirect);
4436 uint16_t size;
4437 eOmc_PID_t eoPID;
4438 if(! askRemoteValue(protoid, &eoPID, size))
4439 return false;
4440
4441 copyPid_eo2iCub(&eoPID, pid);
4442
4443 return true;
4444
4445 //return NOT_YET_IMPLEMENTED("Our boards do not have a Velocity Pid");
4446}
4447
4448bool embObjMotionControl::helper_getVelPidsRaw(Pid *pid)
4449{
4450 std::vector <eOmc_PID_t> eoPIDList (_njoints);
4451 bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_config_piddirect, eoPIDList);
4452 if(!ret)
4453 return false;
4454
4455 for(int j=0; j<_njoints; j++)
4456 {
4457 copyPid_eo2iCub(&eoPIDList[j], &pid[j]);
4458 }
4459
4460 return true;
4461
4462 //return NOT_YET_IMPLEMENTED("Our boards do not have a Velocity Pid");
4463}
4464
4465// PositionDirect Interface
4467{
4468 int mode = 0;
4469 getControlModeRaw(j, &mode);
4470 if (mode != VOCAB_CM_POSITION_DIRECT &&
4471 mode != VOCAB_CM_IDLE)
4472 {
4473 if(event_downsampler->canprint())
4474 {
4475 yError() << "setReferenceRaw: skipping command because" << getBoardInfo() << " joint " << j << " is not in VOCAB_CM_POSITION_DIRECT mode";
4476 }
4477 return true;
4478 }
4479
4480 eOprotID32_t protoId = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_setpoint);
4481 eOmc_setpoint_t setpoint = {0};
4482
4483 _ref_positions[j] = ref; // save internally the new value of pos.
4484 setpoint.type = (eOenum08_t) eomc_setpoint_positionraw;
4485 setpoint.to.position.value = (eOmeas_position_t) S_32(ref);
4486 setpoint.to.position.withvelocity = 0;
4487
4488 return res->setRemoteValue(protoId, &setpoint);
4489}
4490
4491bool embObjMotionControl::setPositionsRaw(const int n_joint, const int *joints, const double *refs)
4492{
4493 bool ret = true;
4494 for(int i=0; i<n_joint; i++)
4495 {
4496 ret &= setPositionRaw(joints[i], refs[i]);
4497 }
4498 return ret;
4499}
4500
4502{
4503 bool ret = true;
4504 for (int i = 0; i<_njoints; i++)
4505 {
4506 ret &= setPositionRaw(i, refs[i]);
4507 }
4508 return ret;
4509}
4510
4511
4513{
4514 if (axis<0 || axis>_njoints) return false;
4515#if ASK_REFERENCE_TO_FIRMWARE
4516 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, axis, eoprot_tag_mc_joint_status_target);
4517 *ref = 0;
4518
4519 // Get the value
4520 uint16_t size;
4521 eOmc_joint_status_target_t target = {0};
4522 if(!askRemoteValue(id32, &target, size))
4523 {
4524 yError() << "embObjMotionControl::getTargetPositionRaw() could not read reference pos for " << getBoardInfo() << "joint " << axis;
4525 return false;
4526 }
4527
4528 *ref = (double) target.trgt_position;
4529 //yError() << "embObjMotionControl::getTargetPositionRaw() BOARD" << _fId.boardNumber << "joint " << axis << "pos=" << target.trgt_position;
4530 return true;
4531#else
4532 *ref = _ref_command_positions[axis];
4533 return true;
4534#endif
4535}
4536
4538{
4539 bool ret = true;
4540 for (int i = 0; i<_njoints; i++)
4541 {
4542 ret &= getTargetPositionRaw(i, &refs[i]);
4543 }
4544 return ret;
4545}
4546
4547bool embObjMotionControl::getTargetPositionsRaw(int nj, const int * jnts, double *refs)
4548{
4549 bool ret = true;
4550 for (int i = 0; i<nj; i++)
4551 {
4552 ret &= getTargetPositionRaw(jnts[i], &refs[i]);
4553 }
4554 return ret;
4555}
4556
4558{
4559 if (axis<0 || axis>_njoints) return false;
4560#if ASK_REFERENCE_TO_FIRMWARE
4561 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, axis, eoprot_tag_mc_joint_status_target);
4562 *ref = 0;
4563
4564 // Get the value
4565 uint16_t size;
4566 eOmc_joint_status_target_t target = {0};
4567 if(!askRemoteValue(id32, &target, size))
4568 {
4569 yError() << "embObjMotionControl::getRefVelocityRaw() could not read reference vel for " << getBoardInfo() << "joint " << axis;
4570 return false;
4571 }
4572 *ref = (double) target.trgt_velocity;
4573 return true;
4574#else
4575 *ref = _ref_command_speeds[axis];
4576 return true;
4577#endif
4578}
4579
4581{
4582 #if ASK_REFERENCE_TO_FIRMWARE
4583 std::vector <eOmc_joint_status_target_t> targetList(_njoints);
4584 bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_status_target, targetList);
4585 if(!ret)
4586 {
4587 yError() << "embObjMotionControl::getRefVelocitiesRaw() could not read reference vel for " << getBoardInfo() ;
4588 return false;
4589 }
4590 // Get the value
4591 for(int j=0; j<_njoints; j++)
4592 {
4593 refs[j] = (double) targetList[j].trgt_velocity;
4594 }
4595 return true;
4596 #else
4597 for(int j=0; j<_njoints; j++)
4598 {
4599 refs[j] = _ref_command_speeds[j];
4600 }
4601 return true;
4602 #endif
4603}
4604
4605bool embObjMotionControl::getRefVelocitiesRaw(int nj, const int * jnts, double *refs)
4606{
4607 std::vector <double> refsList(_njoints);
4608 if(!getRefVelocitiesRaw(refsList.data()))
4609 return false;
4610
4611 for (int i = 0; i<nj; i++)
4612 {
4613 if(jnts[i]>= _njoints)
4614 {
4615 yError() << getBoardInfo() << "getRefVelocitiesRaw: joint " << jnts[i] << "doesn't exist";
4616 return false;
4617 }
4618 refs[i] = refsList[jnts[i]];
4619 }
4620 return true;
4621}
4622
4624{
4625 if (axis<0 || axis>_njoints) return false;
4626#if ASK_REFERENCE_TO_FIRMWARE
4627 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, axis, eoprot_tag_mc_joint_status_target);
4628 *ref = 0;
4629 // Get the value
4630 uint16_t size;
4631 eOmc_joint_status_target_t target = {0};
4632 if(!askRemoteValue(id32, &target, size))
4633 {
4634 yError() << "embObjMotionControl::getRefPositionRaw() could not read reference pos for " << getBoardInfo() << "joint " << axis;
4635 return false;
4636 }
4637
4638 *ref = (double) target.trgt_positionraw;
4639 return true;
4640#else
4641 *ref = _ref_positions[axis];
4642 return true;
4643#endif
4644}
4645
4647{
4648 #if ASK_REFERENCE_TO_FIRMWARE
4649 std::vector <eOmc_joint_status_target_t> targetList(_njoints);
4650 bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_status_target, targetList);
4651 if(!ret)
4652 {
4653 yError() << "embObjMotionControl::getRefPositionRaw() could not read reference pos for " << getBoardInfo();
4654 return false;
4655 }
4656 // Get the value
4657 for(int j=0; j< _njoints; j++)
4658 refs[j] = (double) targetList[j].trgt_positionraw;
4659 return true;
4660 #else
4661 for(int j=0; j< _njoints; j++)
4662 refs[j] = _ref_positions[j];
4663 return true;
4664 #endif
4665}
4666
4667bool embObjMotionControl::getRefPositionsRaw(int nj, const int * jnts, double *refs)
4668{
4669 bool ret = true;
4670 for (int i = 0; i<nj; i++)
4671 {
4672 ret &= getRefPositionRaw(jnts[i], &refs[i]);
4673 }
4674 return ret;
4675}
4676
4677// InteractionMode
4678
4679
4680
4681bool embObjMotionControl::getInteractionModeRaw(int j, yarp::dev::InteractionModeEnum* _mode)
4682{
4683 eOenum08_t interactionmodestatus;
4684// std::cout << "eoMC getInteractionModeRaw SINGLE joint " << j << std::endl;
4685
4686 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core_modes_interactionmodestatus);
4687 if(! res->getLocalValue(protid, &interactionmodestatus)) // it is broadcasted toghether with the jointStatus full
4688 return false;
4689
4690 int tmp = (int) *_mode;
4691 if(!interactionModeStatusConvert_embObj2yarp(interactionmodestatus, tmp) )
4692 return false;
4693
4694 *_mode = (yarp::dev::InteractionModeEnum) tmp;
4695 return true;
4696}
4697
4698bool embObjMotionControl::getInteractionModesRaw(int n_joints, int *joints, yarp::dev::InteractionModeEnum* modes)
4699{
4700// std::cout << "eoMC getInteractionModeRaw GROUP joints" << std::endl;
4701 bool ret = true;
4702 for(int idx=0; idx<n_joints; idx++)
4703 {
4704 ret = getInteractionModeRaw(joints[idx], &modes[idx]);
4705 }
4706 return ret;
4707}
4708
4709bool embObjMotionControl::getInteractionModesRaw(yarp::dev::InteractionModeEnum* modes)
4710{
4711// std::cout << "eoMC getInteractionModeRaw ALL joints" << std::endl;
4712 bool ret = true;
4713 for(int j=0; j<_njoints; j++)
4714 ret = ret && getInteractionModeRaw(j, &modes[j]);
4715 return ret;
4716}
4717
4718// marco.accame: con alberto cardellino abbiamo parlato della correttezza di effettuare la verifica di quanto imposto (in setInteractionModeRaw() ed affini)
4719// andando a rileggere il valore nella scheda eth fino a che esso non sia quello atteso. si deve fare oppure no?
4720// con il interaction mode il can ora non lo fa. mentre lo fa per il control mode. perche' diverso?
4721bool embObjMotionControl::setInteractionModeRaw(int j, yarp::dev::InteractionModeEnum _mode)
4722{
4723 eOenum08_t interactionmodecommand = 0;
4724
4725
4726 // yDebug() << "received setInteractionModeRaw command (SINGLE) for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(_mode);
4727
4728 if (_mode == VOCAB_IM_COMPLIANT && _trq_pids[j].enabled == false) {yError()<<"Torque control is disabled. Check your configuration parameters"; return false;}
4729
4730 if(!interactionModeCommandConvert_yarp2embObj(_mode, interactionmodecommand) )
4731 {
4732 yError() << "setInteractionModeRaw: received unknown mode for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(_mode);
4733 }
4734
4735 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_interactionmode);
4736
4737 if(false == res->setRemoteValue(protid, &interactionmodecommand) )
4738 {
4739 yError() << "setInteractionModeRaw failed for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(_mode);
4740 return false;
4741 }
4742
4743 // marco.accame: use the following if you want to check the value of interactionmode on the remote board
4744#if 0
4745 eOenum08_t interactionmodestatus = 0;
4746 uint16_t size = 0;
4747 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_interactionmodestatus);
4748 bool ret = askRemoteValue(id32, &interactionmodestatus, size);
4749
4750 if((false == ret) || (interactionmodecommand != interactionmodestatus))
4751 {
4752 yError() << "check of embObjMotionControl::setInteractionModeRaw() failed for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(_mode);
4753 return false;
4754 }
4755#endif
4756
4757 return true;
4758}
4759
4760
4761bool embObjMotionControl::setInteractionModesRaw(int n_joints, int *joints, yarp::dev::InteractionModeEnum* modes)
4762{
4763// std::cout << "setInteractionModeRaw GROUP " << std::endl;
4764
4765 eOenum08_t interactionmodecommand = 0;
4766
4767 for(int j=0; j<n_joints; j++)
4768 {
4769 if (modes[j] == VOCAB_IM_COMPLIANT && _trq_pids[j].enabled == false) {yError()<<"Torque control is disabled. Check your configuration parameters"; continue;}
4770
4771 if(!interactionModeCommandConvert_yarp2embObj(modes[j], interactionmodecommand) )
4772 {
4773 yError() << "embObjMotionControl::setInteractionModesRaw(): received unknown interactionMode for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(modes[j]) << " " << modes[j];
4774 return false;
4775 }
4776
4777 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_interactionmode);
4778 if(false == res->setRemoteValue(protid, &interactionmodecommand) )
4779 {
4780 yError() << "embObjMotionControl::setInteractionModesRaw() failed for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(modes[j]);
4781 return false;
4782 }
4783
4784 // marco.accame: use the following if you want to check the value of interactionmode on the remote board
4785#if 0
4786 eOenum08_t interactionmodestatus = 0;
4787 uint16_t size = 0;
4788 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_interactionmodestatus);
4789 bool ret = askRemoteValue(id32, &interactionmodestatus, size);
4790
4791 if((false == ret) || (interactionmodecommand != interactionmodestatus))
4792 {
4793 if(false == ret)
4794 {
4795 yError() << "check of embObjMotionControl::setInteractionModesRaw() failed for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(modes[j]);
4796 return false;
4797 }
4798
4799 int tmp;
4800 if(interactionModeStatusConvert_embObj2yarp(interactionmodestatus, tmp) )
4801 yError() << "setInteractionModeRaw failed for" << getBoardInfo() << " joint " << j << " because of interactionMode mismatching \n\tSet " \
4802 << Vocab32::decode(modes[j]) << " Got " << Vocab32::decode(tmp);
4803 else
4804 yError() << "setInteractionModeRaw failed for" << getBoardInfo() << " joint " << j << " because of interactionMode mismatching \n\tSet " \
4805 << Vocab32::decode(modes[j]) << " Got an unknown value!";
4806 return false;
4807 }
4808#endif
4809
4810 }
4811
4812 return true;
4813}
4814
4815bool embObjMotionControl::setInteractionModesRaw(yarp::dev::InteractionModeEnum* modes)
4816{
4817
4818 eOenum08_t interactionmodecommand = 0;
4819
4820 for(int j=0; j<_njoints; j++)
4821 {
4822 if ((modes[j] == VOCAB_IM_COMPLIANT) && (_trq_pids[j].enabled == false))
4823 {
4824 yError()<<"Torque control is disabled. Check your configuration parameters";
4825 continue;
4826 }
4827
4828 if(!interactionModeCommandConvert_yarp2embObj(modes[j], interactionmodecommand) )
4829 {
4830 yError() << "setInteractionModeRaw: received unknown interactionMode for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(modes[j]);
4831 return false;
4832 }
4833
4834 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_interactionmode);
4835 if(false == res->setRemoteValue(protid, &interactionmodecommand) )
4836 {
4837 yError() << "setInteractionModeRaw failed for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(modes[j]);
4838 return false;
4839 }
4840
4841 // marco.accame: use the following if you want to check the value of interactionmode on the remote board
4842#if 0
4843 eOenum08_t interactionmodestatus = 0;
4844 uint16_t size = 0;
4845 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_interactionmodestatus);
4846 bool ret = askRemoteValue(id32, &interactionmodestatus, size);
4847
4848 if((false == ret) || (interactionmodecommand != interactionmodestatus))
4849 {
4850 if(false == ret)
4851 {
4852 yError() << "check of embObjMotionControl::setInteractionModesRaw() failed for" << getBoardInfo() << " joint " << j << " mode " << Vocab32::decode(modes[j]);
4853 return false;
4854 }
4855
4856 int tmp;
4857 if(interactionModeStatusConvert_embObj2yarp(interactionmodestatus, tmp) )
4858 yError() << "setInteractionModeRaw failed for" << getBoardInfo() << " joint " << j << " because of interactionMode mismatching \n\tSet " \
4859 << Vocab32::decode(modes[j]) << " Got " << Vocab32::decode(tmp);
4860 else
4861 yError() << "setInteractionModeRaw failed for" << getBoardInfo() << " joint " << j << " because of interactionMode mismatching \n\tSet " \
4862 << Vocab32::decode(modes[j]) << " Got an unknown value!";
4863 return false;
4864 }
4865#endif
4866
4867 }
4868
4869 return true;
4870}
4871
4872
4873bool embObjMotionControl::getPidOutputRaw(const PidControlTypeEnum& pidtype, int j, double *out)
4874{
4875 eOprotID32_t protoId = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_core);
4876 eOmc_joint_status_core_t jcore = {0};
4877 *out = 0;
4878 if(!res->getLocalValue(protoId, &jcore) )
4879 return false;
4880
4881 switch (pidtype)
4882 {
4883 case VOCAB_PIDTYPE_POSITION:
4884 if((eomc_controlmode_torque == jcore.modes.controlmodestatus) || (eomc_controlmode_current == jcore.modes.controlmodestatus))
4885 *out=0;
4886 else
4887 *out = (double) jcore.ofpid.generic.output;
4888 break;
4889 //case VOCAB_PIDTYPE_DIRECT:
4890 // *out=0;
4891 //break;
4892 case VOCAB_PIDTYPE_TORQUE:
4893 if ((eomc_controlmode_torque == jcore.modes.controlmodestatus) ||
4894 ((eomc_controlmode_position == jcore.modes.controlmodestatus) && (eOmc_interactionmode_compliant == jcore.modes.interactionmodestatus)))
4895 *out = jcore.ofpid.generic.output;
4896 else
4897 *out = 0;
4898 break;
4899 case VOCAB_PIDTYPE_CURRENT:
4900 *out=0;
4901 break;
4902 case VOCAB_PIDTYPE_VELOCITY:
4903 *out = 0;
4904 break;
4905 default:
4906 yError()<<"Invalid pidtype:"<<pidtype;
4907 break;
4908 }
4909 return true;
4910}
4911
4912bool embObjMotionControl::getPidOutputsRaw(const PidControlTypeEnum& pidtype, double *outs)
4913{
4914 bool ret = true;
4915 for(int j=0; j< _njoints; j++)
4916 {
4917 ret &= getPidOutputRaw(pidtype, j, &outs[j]);
4918 }
4919 return ret;
4920}
4921
4922bool embObjMotionControl::isPidEnabledRaw(const PidControlTypeEnum& pidtype, int j, bool* enabled)
4923{
4924 return NOT_YET_IMPLEMENTED("isPidEnabled");
4925}
4926
4928{
4929 *num=_njoints;
4930 return true;
4931}
4932
4934{
4935 eOmc_motor_status_basic_t status;
4936 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_status_basic);
4937
4938 *val = NAN;
4939 if (_temperatureSensorsVector.at(m)->getType() == motor_temperature_sensor_none)
4940 return true;
4941
4942
4943 bool ret = res->getLocalValue(protid, &status);
4944 if(!ret)
4945 {
4946 yError() << getBoardInfo() << "At timestamp" << yarp::os::Time::now() << "In motor" << m << "embObjMotionControl::getTemperatureRaw failed to complete getLocalValue()";
4947 return ret;
4948 }
4949
4950 *val = _temperatureSensorsVector.at(m)->convertRawToTempCelsius((double)status.mot_temperature);
4951
4952
4953 return ret;
4954}
4955
4957{
4958 bool ret = true;
4959 for(int j=0; j< _njoints; j++)
4960 {
4961 ret &= getTemperatureRaw(j, &vals[j]);
4962 }
4963 return ret;
4964}
4965
4967{
4968 *temp= _temperatureLimits[m].warningTemperatureLimit;
4969
4970 return true;
4971}
4972
4974{
4975 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_config_temperaturelimit);
4976 eOmeas_temperature_t temperatureLimit = (eOmeas_pwm_t) S_16(temp);
4977 return res->setRemoteValue(protid, &temperatureLimit);
4978
4979}
4980
4982{
4983 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_config_currentlimits);
4984 uint16_t size;
4985 eOmc_current_limits_params_t currentlimits = {0};
4986 *val = 0;
4987 if(!askRemoteValue(protid, &currentlimits, size))
4988 {
4989 yError() << "embObjMotionControl::getPeakCurrentRaw() can't read current limits for" << getBoardInfo() << " motor " << m;
4990 return false;
4991 }
4992
4993 *val = (double) currentlimits.peakCurrent ;
4994 return true;
4995}
4996
4997bool embObjMotionControl::setPeakCurrentRaw(int m, const double val)
4998{
4999 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_config_currentlimits);
5000 //get current limit params
5001 uint16_t size;
5002 eOmc_current_limits_params_t currentlimits = {0};
5003 if(!askRemoteValue(protid, &currentlimits, size))
5004 {
5005 yError() << "embObjMotionControl::setPeakCurrentRaw can't read current limits for" << getBoardInfo() << " motor " << m ;
5006 return false;
5007 }
5008
5009 //set current overload
5010 currentlimits.peakCurrent = (eOmeas_current_t) S_16(val);
5011
5012 //send new values
5013 bool ret = res->setRemoteValue(protid, &currentlimits);
5014 if(!ret)
5015 {
5016 yError() << "embObjMotionControl::setPeakCurrentRaw failed sending new value for" << getBoardInfo() << " motor " << m ;
5017 }
5018 return ret;
5019}
5020
5022{
5023 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_config_currentlimits);
5024 uint16_t size;
5025 eOmc_current_limits_params_t currentlimits = {0};
5026 *val = 0;
5027 if(!askRemoteValue(protid, &currentlimits, size))
5028 {
5029 yError() << "embObjMotionControl::getNominalCurrentRaw() can't read current limits for" << getBoardInfo() << " motor " << m;
5030 return false;
5031 }
5032
5033 *val = (double) currentlimits.nominalCurrent ;
5034 return true;
5035}
5036
5038{
5039 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, m, eoprot_tag_mc_motor_config_currentlimits);
5040
5041 //get current limit params
5042 uint16_t size;
5043 eOmc_current_limits_params_t currentlimits = {0};
5044 if(!askRemoteValue(protid, &currentlimits, size))
5045 {
5046 yError() << "embObjMotionControl::setNominalCurrentRaw can't read current limits for" << getBoardInfo() << " motor " << m ;
5047 return false;
5048 }
5049
5050 //set current overload
5051 currentlimits.nominalCurrent = (eOmeas_current_t) S_16(val);
5052
5053 //send new values
5054 bool ret = res->setRemoteValue(protid, &currentlimits);
5055 if(!ret)
5056 {
5057 yError() << "embObjMotionControl::setNominalCurrentRaw failed sending new value for" << getBoardInfo() << " motor " << m ;
5058 }
5059
5060 return ret;
5061}
5062
5063bool embObjMotionControl::getPWMRaw(int j, double* val)
5064{
5065 eOmc_motor_status_basic_t status;
5066 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_status_basic);
5067
5068 bool ret = res->getLocalValue(protid, &status);
5069 if(ret)
5070 {
5071 *val = (double) status.mot_pwm;
5072 }
5073 else
5074 {
5075 yError() << "embObjMotionControl::getPWMRaw failed for" << getBoardInfo() << " motor " << j ;
5076 *val = 0;
5077 }
5078
5079 return ret;
5080}
5081
5083{
5084 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config_pwmlimit);
5085 uint16_t size;
5086 eOmeas_pwm_t motorPwmLimit;
5087
5088 bool ret = askRemoteValue(protid, &motorPwmLimit, size);
5089 if(ret)
5090 {
5091 *val = (double) motorPwmLimit;
5092 }
5093 else
5094 {
5095 yError() << "embObjMotionControl::getPWMLimitRaw failed for" << getBoardInfo() << " motor " << j ;
5096 *val = 0;
5097 }
5098
5099 return ret;
5100}
5101
5102bool embObjMotionControl::setPWMLimitRaw(int j, const double val)
5103{
5104 if (val < 0)
5105 {
5106 yError() << "embObjMotionControl::setPWMLimitRaw failed because pwmLimit is negative for" << getBoardInfo() << " motor " << j ;
5107 return true; //return true because the error ios not due to communication error
5108 }
5109 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config_pwmlimit);
5110 eOmeas_pwm_t motorPwmLimit = (eOmeas_pwm_t) S_16(val);
5111 return res->setRemoteValue(protid, &motorPwmLimit);
5112}
5113
5115{
5116 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_controller, 0, eoprot_tag_mc_controller_status);
5117 uint16_t size;
5118 eOmc_controller_status_t controllerStatus;
5119
5120 bool ret = askRemoteValue(protid, &controllerStatus, size);
5121 if(ret)
5122 {
5123 *val = (double) controllerStatus.supplyVoltage;
5124 }
5125 else
5126 {
5127 yError() << "embObjMotionControl::getPowerSupplyVoltageRaw failed for" << getBoardInfo() << " motor " << j ;
5128 *val = 0;
5129 }
5130
5131 return ret;
5132}
5133
5134bool embObjMotionControl::askRemoteValue(eOprotID32_t id32, void* value, uint16_t& size)
5135{
5136 return res->getRemoteValue(id32, value, 0.200, 0);
5137}
5138
5139
5140template <class T>
5141bool embObjMotionControl::askRemoteValues(eOprotEndpoint_t ep, eOprotEntity_t entity, eOprotTag_t tag, std::vector<T>& values)
5142{
5143 std::vector<eOprotID32_t> idList;
5144 std::vector<void*> valueList;
5145 idList.clear();
5146 valueList.clear();
5147 for(int j=0; j<_njoints; j++)
5148 {
5149 eOprotID32_t protoId = eoprot_ID_get(ep, entity, j, tag);
5150 idList.push_back(protoId);
5151 valueList.push_back((void*)&values[j]);
5152 }
5153
5154 bool ret = res->getRemoteValues(idList, valueList);
5155 if(!ret)
5156 {
5157 yError() << "embObjMotionControl::askRemoteValues failed for all joints of" << getBoardInfo();
5158 }
5159
5160 return ret;
5161}
5162
5163
5164
5165
5166bool embObjMotionControl::checkRemoteControlModeStatus(int joint, int target_mode)
5167{
5168 bool ret = false;
5169 eOenum08_t temp = 0;
5170 uint16_t size = 0;
5171
5172 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, joint, eoprot_tag_mc_joint_status_core_modes_controlmodestatus);
5173 const double timeout = 0.250; // 250 msec
5174 const int maxretries = 25;
5175 const double delaybetweenqueries = 0.010; // 10 msec
5176
5177 // now i repeat the query until i am satisfied. how many times? for maximum time timeout seconds and with a gap of delaybetweenqueries
5178
5179 double timeofstart = yarp::os::Time::now();
5180 int attempt = 0;
5181
5182 for( attempt = 0; attempt < maxretries; attempt++)
5183 {
5184 ret = askRemoteValue(id32, &temp, size);
5185 if(ret == false)
5186 {
5187 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());
5188 break;
5189 }
5190 int current_mode = controlModeStatusConvert_embObj2yarp(temp);
5191 if(current_mode == target_mode)
5192 {
5193 ret = true;
5194 break;
5195 }
5196 if((current_mode == VOCAB_CM_IDLE) && (target_mode == VOCAB_CM_FORCE_IDLE))
5197 {
5198 ret = true;
5199 break;
5200 }
5201 if(current_mode == VOCAB_CM_HW_FAULT)
5202 {
5203 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()); }
5204 ret = true;
5205 break;
5206 }
5207
5208 if((yarp::os::Time::now()-timeofstart) > timeout)
5209 {
5210 ret = false;
5211 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());
5212 break;
5213 }
5214 if(attempt > 0)
5215 { // i print the warning only after at least one retry.
5216 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());
5217 }
5218 SystemClock::delaySystem(delaybetweenqueries);
5219 }
5220
5221 if(false == ret)
5222 {
5223 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);
5224 }
5225
5226
5227 return ret;
5228}
5229
5230//the device needs coupling info if it manages joints controlled by 2foc and mc4plus.
5231bool embObjMotionControl::iNeedCouplingsInfo(void)
5232{
5233 eOmn_serv_type_t mc_serv_type = (eOmn_serv_type_t)serviceConfig.ethservice.configuration.type;
5234 if( (mc_serv_type == eomn_serv_MC_foc) ||
5235 (mc_serv_type == eomn_serv_MC_mc4plus) ||
5236 (mc_serv_type == eomn_serv_MC_mc4plusmais) ||
5237 (mc_serv_type == eomn_serv_MC_mc2pluspsc) ||
5238 (mc_serv_type == eomn_serv_MC_mc4plusfaps) ||
5239 (mc_serv_type == eomn_serv_MC_advfoc)
5240 )
5241 return true;
5242 else
5243 return false;
5244}
5245
5246//PWM interface
5248{
5249 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_setpoint);
5250
5251 eOmc_setpoint_t setpoint;
5252
5253 setpoint.type = (eOenum08_t)eomc_setpoint_openloop;
5254 setpoint.to.openloop.value = (eOmeas_pwm_t)S_16(v);
5255
5256 return res->setRemoteValue(protid, &setpoint);
5257}
5258
5260{
5261 bool ret = true;
5262 for (int j = 0; j<_njoints; j++)
5263 {
5264 ret = ret && setRefDutyCycleRaw(j, v[j]);
5265 }
5266 return ret;
5267}
5268
5270{
5271 eOprotID32_t protoId = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_target);
5272 uint16_t size = 0;
5273 *v = 0;
5274 eOmc_joint_status_target_t target = { 0 };
5275
5276
5277 if (!askRemoteValue(protoId, &target, size))
5278 {
5279 yError() << "embObjMotionControl::getRefDutyCycleRaw() could not read openloop reference for " << getBoardInfo() << "joint " << j;
5280 return false;
5281 }
5282
5283 *v = (double)target.trgt_pwm;
5284
5285 return true;
5286}
5287
5289{
5290 std::vector <eOmc_joint_status_target_t> targetList(_njoints);
5291 bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_status_target, targetList);
5292 if(!ret)
5293 {
5294 yError() << "embObjMotionControl::getDutyCyclesRaw failed for all joints of" << getBoardInfo();
5295 }
5296
5297 for (int j = 0; j<_njoints; j++)
5298 {
5299 v[j]= targetList[j].trgt_pwm;
5300 }
5301 return ret;
5302}
5303
5305{
5306 eOmc_motor_status_basic_t status;
5307 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_status_basic);
5308
5309 bool ret = res->getLocalValue(protid, &status);
5310 if (ret)
5311 {
5312 *v = (double)status.mot_pwm;
5313 }
5314 else
5315 {
5316 yError() << "embObjMotionControl::getDutyCycleRaw failed for" << getBoardInfo() << " motor " << j;
5317 *v = 0;
5318 }
5319
5320 return ret;
5321}
5322
5324{
5325 bool ret = true;
5326 for (int j = 0; j< _njoints; j++)
5327 {
5328 ret &= getDutyCycleRaw(j, &v[j]);
5329 }
5330 return ret;
5331}
5332
5333// Current interface
5334
5335bool embObjMotionControl::getCurrentRangeRaw(int j, double *min, double *max)
5336{
5337 //this should be completed with numbers obtained from configuration files.
5338 //some caveats: currently current limits are expressed in robot configuration files in milliAmperes. Amperes should be used instead.
5339 //yarp does not perform any conversion on these numbers. Should it?
5340 *min = -10000.0;
5341 *max = 10000.0;
5342 return true;
5343}
5344
5345bool embObjMotionControl::getCurrentRangesRaw(double *min, double *max)
5346{
5347 bool ret = true;
5348 for (int j = 0; j< _njoints; j++)
5349 {
5350 ret &= getCurrentRangeRaw(j, &min[j], &max[j]);
5351 }
5352 return ret;
5353}
5354
5356{
5357 bool ret = true;
5358 for (int j = 0; j<_njoints; j++)
5359 {
5360 ret = ret && setRefCurrentRaw(j, t[j]);
5361 }
5362 return ret;
5363}
5364
5366{
5367 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_cmmnds_setpoint);
5368
5369 eOmc_setpoint_t setpoint;
5370
5371 setpoint.type = (eOenum08_t)eomc_setpoint_current;
5372 setpoint.to.current.value = (eOmeas_pwm_t)S_16(t);
5373
5374 return res->setRemoteValue(protid, &setpoint);
5375}
5376
5377bool embObjMotionControl::setRefCurrentsRaw(const int n_joint, const int *joints, const double *t)
5378{
5379 bool ret = true;
5380 for (int j = 0; j<n_joint; j++)
5381 {
5382 ret = ret && setRefCurrentRaw(joints[j], t[j]);
5383 }
5384 return ret;
5385}
5386
5388{
5389 std::vector <eOmc_joint_status_target_t> targetList(_njoints);
5390 bool ret = askRemoteValues(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, eoprot_tag_mc_joint_status_target, targetList);
5391 if (!ret)
5392 {
5393 yError() << "embObjMotionControl::getDutyCyclesRaw failed for all joints of" << getBoardInfo();
5394 }
5395
5396 for (int j = 0; j<_njoints; j++)
5397 {
5398 t[j] = targetList[j].trgt_current;
5399 }
5400 return ret;
5401}
5402
5404{
5405 eOprotID32_t protoId = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_target);
5406 uint16_t size = 0;
5407 *t = 0;
5408 eOmc_joint_status_target_t target = { 0 };
5409
5410
5411 if (!askRemoteValue(protoId, &target, size))
5412 {
5413 yError() << "embObjMotionControl::getRefDutyCycleRaw() could not read openloop reference for " << getBoardInfo() << "joint " << j;
5414 return false;
5415 }
5416
5417 *t = (double)target.trgt_current;
5418
5419 return true;
5420}
5421
5422bool embObjMotionControl::helper_setCurPidRaw(int j, const Pid &pid)
5423{
5424 eOprotID32_t protoId = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config_pidcurrent);
5425 eOmc_PID_t outPid;
5426 Pid hwPid = pid;
5427
5428 if (!_cur_pids[j].enabled)
5429 {
5430 yError() << "eoMc " << getBoardInfo() << ": it is not possible set current pid for motor " << j << ", because current pid is not enabled in xml files";
5431 return false;
5432 }
5433
5434 copyPid_iCub2eo(&hwPid, &outPid);
5435
5436 if (false == res->setRemoteValue(protoId, &outPid))
5437 {
5438 yError() << "while setting velocity PIDs for" << getBoardInfo() << " joint " << j;
5439 return false;
5440 }
5441
5442 return true;
5443
5444 //return NOT_YET_IMPLEMENTED("Our boards do not have a Velocity Pid");
5445}
5446
5447bool embObjMotionControl::helper_setSpdPidRaw(int j, const Pid &pid)
5448{
5449 eOprotID32_t protoId = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config_pidspeed);
5450 eOmc_PID_t outPid;
5451 Pid hwPid = pid;
5452
5453 if (!_cur_pids[j].enabled)
5454 {
5455 yError() << "eoMc " << getBoardInfo() << ": it is not possible set speed pid for motor " << j << ", because speed pid is not enabled in xml files";
5456 return false;
5457 }
5458
5459 copyPid_iCub2eo(&hwPid, &outPid);
5460
5461 if (false == res->setRemoteValue(protoId, &outPid))
5462 {
5463 yError() << "while setting velocity PIDs for" << getBoardInfo() << " joint " << j;
5464 return false;
5465 }
5466
5467 return true;
5468
5469 //return NOT_YET_IMPLEMENTED("Our boards do not have a Velocity Pid");
5470}
5471
5472bool embObjMotionControl::helper_getCurPidRaw(int j, Pid *pid)
5473{
5474 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
5475 uint16_t size;
5476 eOmc_motor_config_t motor_cfg;
5477 if(! askRemoteValue(protoid, &motor_cfg, size))
5478 return false;
5479
5480 // refresh cached value when reading data from the EMS
5481 eOmc_PID_t tmp = (eOmc_PID_t)motor_cfg.pidcurrent;
5482 copyPid_eo2iCub(&tmp, pid);
5483
5484 return true;
5485}
5486
5487bool embObjMotionControl::helper_getSpdPidRaw(int j, Pid *pid)
5488{
5489 eOprotID32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, j, eoprot_tag_mc_motor_config);
5490 uint16_t size;
5491 eOmc_motor_config_t motor_cfg;
5492 if (!askRemoteValue(protoid, &motor_cfg, size))
5493 return false;
5494
5495 // refresh cached value when reading data from the EMS
5496 eOmc_PID_t tmp = (eOmc_PID_t)motor_cfg.pidspeed;
5497 copyPid_eo2iCub(&tmp, pid);
5498
5499 return true;
5500}
5501
5502bool embObjMotionControl::helper_getCurPidsRaw(Pid *pid)
5503{
5504 std::vector <eOmc_motor_config_t> motor_cfg_list(_njoints);
5505 bool ret = askRemoteValues<eOmc_motor_config_t>(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, eoprot_tag_mc_motor_config, motor_cfg_list);
5506 if(! ret)
5507 return false;
5508
5509 for(int j=0; j<_njoints; j++)
5510 {
5511 eOmc_PID_t tmp = (eOmc_PID_t)motor_cfg_list[j].pidcurrent;
5512 copyPid_eo2iCub(&tmp, &pid[j]);
5513 }
5514 return true;
5515}
5516
5517bool embObjMotionControl::helper_getSpdPidsRaw(Pid *pid)
5518{
5519 std::vector <eOmc_motor_config_t> motor_cfg_list(_njoints);
5520 bool ret = askRemoteValues<eOmc_motor_config_t>(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, eoprot_tag_mc_motor_config, motor_cfg_list);
5521 if (!ret)
5522 return false;
5523
5524 for (int j = 0; j<_njoints; j++)
5525 {
5526 eOmc_PID_t tmp = (eOmc_PID_t)motor_cfg_list[j].pidspeed;
5527 copyPid_eo2iCub(&tmp, &pid[j]);
5528 }
5529 return true;
5530}
5531
5532bool embObjMotionControl::getJointConfiguration(int joint, eOmc_joint_config_t *jntCfg_ptr)
5533{
5534 uint32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, joint, eoprot_tag_mc_joint_config);
5535 uint16_t size;
5536 if(!askRemoteValue(protoid, jntCfg_ptr, size))
5537 {
5538 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());
5539 return false;
5540 }
5541 return true;
5542}
5543
5544bool embObjMotionControl::getMotorConfiguration(int axis, eOmc_motor_config_t *motCfg_ptr)
5545{
5546 uint32_t protoid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_motor, axis, eoprot_tag_mc_motor_config);
5547 uint16_t size;
5548 if(!askRemoteValue(protoid, motCfg_ptr, size))
5549 {
5550 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());
5551 return false;
5552 }
5553 return true;
5554}
5555
5556
5557bool embObjMotionControl::getGerabox_E2J(int joint, double *gearbox_E2J_ptr)
5558{
5559 eOmc_joint_config_t jntCfg;
5560
5561 if(!getJointConfiguration(joint, &jntCfg))
5562 {
5563 yError ("Failure embObjMotionControl::getGerabox_E2J(axis=%d) for BOARD %s IP %s", joint, res->getProperties().boardnameString.c_str(), res->getProperties().ipv4addrString.c_str());
5564 return false;
5565 }
5566 *gearbox_E2J_ptr = jntCfg.gearbox_E2J;
5567 return true;
5568}
5569
5570bool embObjMotionControl::getJointEncTolerance(int joint, double *jEncTolerance_ptr)
5571{
5572 eOmc_joint_config_t jntCfg;
5573
5574 if(!getJointConfiguration(joint, &jntCfg))
5575 {
5576 yError ("Failure embObjMotionControl::getJointEncTolerance(axis=%d) for BOARD %s IP %s", joint, res->getProperties().boardnameString.c_str(), res->getProperties().ipv4addrString.c_str());
5577 return false;
5578 }
5579 *jEncTolerance_ptr = jntCfg.jntEncTolerance;
5580 return true;
5581}
5582
5583bool embObjMotionControl::getMotorEncTolerance(int axis, double *mEncTolerance_ptr)
5584{
5585 eOmc_motor_config_t motorCfg;
5586 if(!getMotorConfiguration(axis, &motorCfg))
5587 {
5588 yError ("Failure embObjMotionControl::getMotorEncTolerance(axis=%d) for BOARD %s IP %s", axis, res->getProperties().boardnameString.c_str(), res->getProperties().ipv4addrString.c_str());
5589 return false;
5590 }
5591 *mEncTolerance_ptr = motorCfg.rotEncTolerance;
5592 return true;
5593}
5594
5595bool embObjMotionControl::getLastJointFaultRaw(int j, int& fault, std::string& message)
5596{
5597 eOmc_motor_status_t status;
5598
5599 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol,
5600 eoprot_entity_mc_motor, j,
5601 eoprot_tag_mc_motor_status);
5602
5603 bool ret = res->getLocalValue(protid, &status);
5604
5605 message.clear();
5606
5607 if (!ret)
5608 {
5609 fault = -1;
5610 message = "Could not retrieve the fault state.";
5611 return false;
5612 }
5613
5614 if (status.mc_fault_state == EOERROR_CODE_DUMMY)
5615 {
5616 fault = EOERROR_CODE_DUMMY;
5617 message = "No fault detected.";
5618
5619 return true;
5620 }
5621
5622 fault = eoerror_code2value(status.mc_fault_state);
5623 message = eoerror_code2string(status.mc_fault_state);
5624
5625 return true;
5626}
5627
5628bool embObjMotionControl::getRawData_core(std::string key, std::vector<std::int32_t> &data)
5629{
5630 //Here I need to be sure 100% the key exists!!!
5631 // It must exists since the call is made while iterating over the map
5632 data.clear();
5633 for(int j=0; j< _njoints; j++)
5634 {
5635 eOmc_joint_status_additionalInfo_t addinfo;
5636 eOprotID32_t protid = eoprot_ID_get(eoprot_endpoint_motioncontrol, eoprot_entity_mc_joint, j, eoprot_tag_mc_joint_status_addinfo_multienc);
5637 if(!res->getLocalValue(protid, &addinfo))
5638 {
5639 return false;
5640 }
5641 for (int k = 0; k < std::size(addinfo.multienc); k++)
5642 {
5643 data.push_back((int32_t)addinfo.multienc[k]);
5644 }
5645
5646 }
5647 return true;
5648}
5649
5650bool embObjMotionControl::getRawDataMap(std::map<std::string, std::vector<std::int32_t>> &map)
5651{
5652 for (auto it = _rawValuesMetadataMap.begin(); it != _rawValuesMetadataMap.end(); it++)
5653 {
5654 if(!getRawData_core(it->first, _rawDataAuxVector))
5655 {
5656 yError() << getBoardInfo() << "getRawData failed. Cannot retrieve all raw data from local memory";
5657 return false;
5658 }
5659 map.insert({it->first, _rawDataAuxVector});
5660 }
5661
5662 return true;
5663}
5664
5665bool embObjMotionControl::getRawData(std::string key, std::vector<std::int32_t> &data)
5666{
5667 if(_rawValuesMetadataMap.find(key) != _rawValuesMetadataMap.end())
5668 {
5669 getRawData_core(key, data);
5670 }
5671 else
5672 {
5673 yError() << getBoardInfo() << "Request key:" << key << "is not available. Cannot retrieve get raw data.";
5674 return false;
5675 }
5676
5677 return true;
5678}
5679
5680bool embObjMotionControl::getKeys(std::vector<std::string> &keys)
5681{
5682 for (const auto &p : _rawValuesMetadataMap)
5683 {
5684 keys.push_back(p.first);
5685 }
5686
5687 return true;
5688}
5689
5691{
5692 return _rawValuesMetadataMap.size();
5693}
5694
5696{
5697 if (_rawValuesMetadataMap.empty())
5698 {
5699 yError() << getBoardInfo() << "embObjMotionControl Map is empty. Closing...";
5700 return false;
5701 }
5702
5703 metamap.metadataMap = _rawValuesMetadataMap;
5704 return true;
5705}
5707{
5708 if(_rawValuesMetadataMap.find(key) != _rawValuesMetadataMap.end())
5709 {
5710 meta = _rawValuesMetadataMap[key];
5711 }
5712 else
5713 {
5714 yError() << getBoardInfo() << "Requested key" << key << "is not available in the map. Closing...";
5715 return false;
5716 }
5717
5718
5719 return true;
5720}
5721
5722// 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 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 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 parseTimeoutsGroup(yarp::os::Searchable &config, std::vector< timeouts_t > &timeouts, int defaultVelocityTimeout)
bool parseCurrentLimits(yarp::os::Searchable &config, std::vector< motorCurrentLimits_t > &currLimits)
bool parseEncoderFactor(yarp::os::Searchable &config, double encoderFactor[])
bool parsefullscalePWM(yarp::os::Searchable &config, double dutycycleToPWM[])
bool parseRotorsLimits(yarp::os::Searchable &config, std::vector< rotorLimits_t > &rotorsLimits)
bool parseImpedanceGroup(yarp::os::Searchable &config, std::vector< impedanceParameters_t > &impedance)
bool parseKalmanFilterParams(yarp::os::Searchable &config, std::vector< kalmanFilterParams_t > &kalmanFilterParams)
bool parseGearboxValues(yarp::os::Searchable &config, double gearbox_M2J[], double gearbox_E2J[])
bool parseBehaviourFalgs(yarp::os::Searchable &config, bool &useRawEncoderData, bool &pwmIsLimited)
std::string usernamePidSelected
Definition eomcParser.h:374
yarp::dev::PidFeedbackUnitsEnum fbk_PidUnits
Definition eomcParser.h:368
eOmc_ctrl_out_type_t out_type
Definition eomcParser.h:370
yarp::dev::PidOutputUnitsEnum out_PidUnits
Definition eomcParser.h:369
_3f_vect_t acc
Definition dataTypes.h:1
int n
static uint32_t idx[BOARD_NUM]
static bool nv_not_found(void)
static bool NOT_YET_IMPLEMENTED(const char *txt)
#define PARSER_MOTION_CONTROL_VERSION
static bool DEPRECATED(const char *txt)
int jnts
Definition main.cpp:60
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:88
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:483
std::vector< double > matrixE2J
Definition eomcParser.h:484
std::vector< double > matrixJ2M
Definition eomcParser.h:482