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