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