YARP
Yet Another Robot Platform
ControlBoardWrapper.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * Copyright (C) 2006-2010 RobotCub Consortium
4  * All rights reserved.
5  *
6  * This software may be modified and distributed under the terms of the
7  * BSD-3-Clause license. See the accompanying LICENSE file for details.
8  */
9 
10 #include "ControlBoardWrapper.h"
12 #include "RPCMessagesParser.h"
15 #include <iostream>
16 #include <yarp/os/LogComponent.h>
17 #include <yarp/os/LogStream.h>
18 #include <sstream>
19 #include <numeric>
20 #include <algorithm>
21 
22 #include <cstring> // for memset function
23 
24 using namespace yarp::os;
25 using namespace yarp::dev;
26 using namespace yarp::dev::impl;
27 using namespace yarp::sig;
28 using namespace std;
29 
30 
32  ownDevices(true)
33 {
34  streaming_parser.init(this);
35  RPC_parser.init(this);
36  controlledJoints = 0;
37  period = 0.02; // s.
38  base = 0;
39  top = 0;
40  subDeviceOwned = nullptr;
41  _verb = false;
42 
43  // init ROS data
44  rosNodeName = "";
45  rosTopicName = "";
46  rosNode = nullptr;
47  rosMsgCounter = 0;
48  useROS = ROS_disabled;
49  jointNames.clear();
50 }
51 
52 void ControlBoardWrapper::cleanup_yarpPorts()
53 {
54  //shut down control port
55  inputRPCPort.interrupt();
56  inputRPCPort.removeCallbackLock();
57  inputRPCPort.close();
58 
59  inputStreamingPort.interrupt();
60  inputStreamingPort.close();
61 
62  outputPositionStatePort.interrupt();
63  outputPositionStatePort.close();
64 
65  extendedOutputStatePort.interrupt();
66  extendedOutputStatePort.close();
67 
68  rpcData.destroy();
69 }
70 
72 
74 {
75  //stop thread if running
76  detachAll();
77 
79  {
81  }
82 
83  if(useROS != ROS_only)
84  {
85  cleanup_yarpPorts();
86  }
87 
88  if(rosNode != nullptr)
89  {
90  delete rosNode;
91  rosNode = nullptr;
92  }
93 
94  //if we own a deviced we have to close and delete it
95  if (ownDevices)
96  {
97  // we should have created a new devices which we need to delete
98  if(subDeviceOwned != nullptr)
99  {
100  subDeviceOwned->close();
101  delete subDeviceOwned;
102  subDeviceOwned = nullptr;
103  }
104  }
105  else
106  {
107  detachAll();
108  }
109  return true;
110 }
111 
112 bool ControlBoardWrapper::checkPortName(Searchable &params)
113 {
114  /* see if rootName is present in the config file, this param is not used from long time, so it'll be
115  * marked as deprecated.
116  */
117  if(params.check("rootName"))
118  {
120  "************************************************************************************\n"
121  "* controlboardwrapper2 is using the deprecated parameter 'rootName' for port name, *\n"
122  "* It has to be removed and substituted with: *\n"
123  "* name: full port prefix name with leading '/', e.g. /robotName/part/ *\n"
124  "************************************************************************************";
125  rootName = params.find("rootName").asString();
126  }
127 
128  // find name as port name (similar both in new and old policy
129  if(!params.check("name"))
130  {
132  "************************************************************************************\n"
133  "* controlboardwrapper2 missing mandatory parameter 'name' for port name, usage is: *\n"
134  "* name: full port prefix name with leading '/', e.g. /robotName/part/ *\n"
135  "************************************************************************************";
136  return false;
137  }
138 
139  partName = params.find("name").asString();
140  if(partName[0] != '/')
141  {
143  "************************************************************************************\n"
144  "* controlboardwrapper2 'name' parameter for port name does not follow convention, *\n"
145  "* it MUST start with a leading '/' since it is used as the full prefix port name *\n"
146  "* name: full port prefix name with leading '/', e.g. /robotName/part/ *\n"
147  "* A temporary automatic fix will be done for you, but please fix your config file *\n"
148  "************************************************************************************";
149  rootName = "/" + partName;
150  }
151  else
152  {
153  rootName = partName;
154  }
155 
156  return true;
157 }
158 
159 bool ControlBoardWrapper::checkROSParams(Searchable &config)
160 {
161  // check for ROS parameter group
162  if(!config.check("ROS") )
163  {
164  useROS = ROS_disabled;
165  return true;
166  }
167 
168  yCInfo(CONTROLBOARDWRAPPER) << "ROS group was FOUND in config file.";
169 
170  Bottle &rosGroup = config.findGroup("ROS");
171  if(rosGroup.isNull())
172  {
173  yCError(CONTROLBOARDWRAPPER) << partName << "ROS group params is not a valid group or empty";
174  useROS = ROS_config_error;
175  return false;
176  }
177 
178  // check for useROS parameter
179  if(!rosGroup.check("useROS"))
180  {
181  yCError(CONTROLBOARDWRAPPER) << partName << " cannot find useROS parameter, mandatory when using ROS message. \n \
182  Allowed values are true, false, ROS_only";
183  useROS = ROS_config_error;
184  return false;
185  }
186  std::string ros_use_type = rosGroup.find("useROS").asString();
187  if(ros_use_type == "false")
188  {
189  yCInfo(CONTROLBOARDWRAPPER) << partName << "useROS topic if set to 'false'";
190  useROS = ROS_disabled;
191  return true;
192  }
193  else if(ros_use_type == "true")
194  {
195  yCInfo(CONTROLBOARDWRAPPER) << partName << "useROS topic if set to 'true'";
196  useROS = ROS_enabled;
197  }
198  else if(ros_use_type == "only")
199  {
200  yCInfo(CONTROLBOARDWRAPPER) << partName << "useROS topic if set to 'only";
201  useROS = ROS_only;
202  }
203  else
204  {
205  yCInfo(CONTROLBOARDWRAPPER) << partName << "useROS parameter is seet to unvalid value ('" << ros_use_type << "'), supported values are 'true', 'false', 'only'";
206  useROS = ROS_config_error;
207  return false;
208  }
209 
210  // check for ROS_nodeName parameter
211  if(!rosGroup.check("ROS_nodeName"))
212  {
213  yCError(CONTROLBOARDWRAPPER) << partName << " cannot find ROS_nodeName parameter, mandatory when using ROS message";
214  useROS = ROS_config_error;
215  return false;
216  }
217  rosNodeName = rosGroup.find("ROS_nodeName").asString(); // TODO: check name is correct
218  yCInfo(CONTROLBOARDWRAPPER) << partName << "rosNodeName is " << rosNodeName;
219 
220  // check for ROS_topicName parameter
221  if(!rosGroup.check("ROS_topicName"))
222  {
223  yCError(CONTROLBOARDWRAPPER) << partName << " cannot find rosTopicName parameter, mandatory when using ROS message";
224  useROS = ROS_config_error;
225  return false;
226  }
227  rosTopicName = rosGroup.find("ROS_topicName").asString();
228  yCInfo(CONTROLBOARDWRAPPER) << partName << "rosTopicName is " << rosTopicName;
229 
230  // check for rosNodeName parameter
231  // UPDATE: joint names are got from MotionControl subdevice now.
232  // An error should be thrown later on in case we fail getting names from device
233  if(!rosGroup.check("jointNames"))
234  {
235  yCInfo(CONTROLBOARDWRAPPER) << partName << "ROS topic has been required, jointNames will be got from motionControl subdevice.";
236  }
237  else // if names are there, store them. They will be used for back compatibility if old policy is used.
238  {
239  Bottle nameList = rosGroup.findGroup("jointNames").tail();
240  if (nameList.isNull())
241  {
242  yCError(CONTROLBOARDWRAPPER) << partName << " jointNames not found";
243  useROS = ROS_config_error;
244  return false;
245  }
246 
247  if(nameList.size() != (size_t) controlledJoints)
248  {
249  yCError(CONTROLBOARDWRAPPER) << partName << " jointNames incorrect number of entries. \n jointNames is " << nameList.toString() << "while expected length is " << controlledJoints;
250  useROS = ROS_config_error;
251  return false;
252  }
253 
254  jointNames.clear();
255  for(int i=0; i<controlledJoints; i++)
256  {
257  jointNames.push_back(nameList.get(i).toString());
258  }
259  }
260  return true;
261 }
262 
263 bool ControlBoardWrapper::initialize_ROS()
264 {
265  bool success = false;
266  switch(useROS)
267  {
268  case ROS_enabled:
269  case ROS_only:
270  {
271  rosNode = new yarp::os::Node(rosNodeName); // add a ROS node
272 
273  if(rosNode == nullptr)
274  {
275  yCError(CONTROLBOARDWRAPPER) << " opening " << rosNodeName << " Node, check your yarp-ROS network configuration";
276  success = false;
277  break;
278  }
279 
280  if (!rosPublisherPort.topic(rosTopicName) )
281  {
282  yCError(CONTROLBOARDWRAPPER) << " opening " << rosTopicName << " Topic, check your yarp-ROS network configuration";
283  success = false;
284  break;
285  }
286  success = true;
287  } break;
288 
289  case ROS_disabled:
290  {
291  yCInfo(CONTROLBOARDWRAPPER) << partName << ": no ROS initialization required";
292  success = true;
293  } break;
294 
295  case ROS_config_error:
296  {
297  yCError(CONTROLBOARDWRAPPER) << partName << " ROS parameter are not correct, check your configuration file";
298  success = false;
299  } break;
300 
301  default:
302  {
303  yCError(CONTROLBOARDWRAPPER) << partName << " something went wrong with ROS configuration, we should never be here!!!";
304  success = false;
305  } break;
306  }
307  return success;
308 }
309 
310 bool ControlBoardWrapper::initialize_YARP(yarp::os::Searchable &prop)
311 {
312  bool success = false;
313 
314  switch(useROS)
315  {
316  case ROS_only:
317  {
318  yCInfo(CONTROLBOARDWRAPPER) << partName << " No YARP initialization required";
319  success = true;
320  } break;
321 
322  default:
323  {
324  yCInfo(CONTROLBOARDWRAPPER) << partName << " initting YARP initialization";
325  // initialize callback
326  if (!streaming_parser.initialize())
327  {
328  yCError(CONTROLBOARDWRAPPER) <<"Error could not initialize callback object";
329  success = false;
330  break;
331  }
332 
333  rootName = prop.check("rootName",Value("/"), "starting '/' if needed.").asString();
334  partName=prop.check("name",Value("controlboard"), "prefix for port names").asString();
335  rootName+=(partName);
336  if( rootName.find("//") != std::string::npos )
337  {
338  rootName.replace(rootName.find("//"), 2, "/");
339  }
340 
342  if(! inputRPCPort.open((rootName+"/rpc:i")) )
343  {
344  yCError(CONTROLBOARDWRAPPER) <<"Error opening port "<< rootName+"/rpc:i";
345  success = false;
346  break;
347  }
348  inputRPCPort.setReader(RPC_parser);
349  inputRPC_buffer.attach(inputRPCPort);
350  RPC_parser.attach(inputRPC_buffer);
351 
352  if(!inputStreamingPort.open(rootName+"/command:i") )
353  {
354  yCError(CONTROLBOARDWRAPPER) <<"Error opening port "<< rootName+"/rpc:i";
355  success = false;
356  break;
357  }
358 
359  // attach callback.
360  inputStreamingPort.setStrict();
361  inputStreamingPort.useCallback(streaming_parser);
362 
363  if(!outputPositionStatePort.open(rootName+"/state:o") )
364  {
365  yCError(CONTROLBOARDWRAPPER) <<"Error opening port "<< rootName+"/state:o";
366  success = false;
367  break;
368  }
369 
370  // new extended output state port
371  if(!extendedOutputStatePort.open(rootName+"/stateExt:o") )
372  {
373  yCError(CONTROLBOARDWRAPPER) <<"Error opening port "<< rootName+"/state:o";
374  success = false;
375  break;
376  }
377  extendedOutputState_buffer.attach(extendedOutputStatePort);
378  success = true;
379  } break;
380  } // end switch
381 
382  // cleanup if something went wrong
383  if(!success)
384  {
385  cleanup_yarpPorts();
386  }
387  return success;
388 }
389 
390 
392 {
393  Property prop;
394  prop.fromString(config.toString());
395 
396  _verb = (prop.check("verbose","if present, give detailed output"));
397  if (_verb)
398  yCInfo(CONTROLBOARDWRAPPER, "Running with verbose output");
399 
400  if(!checkPortName(config) )
401  {
402  yCError(CONTROLBOARDWRAPPER) << "'portName' was not correctly set, check you r configuration file";
403  return false;
404  }
405 
406  // check FIRST for deprecated parameter
407  if(prop.check("threadrate"))
408  {
409  yCError(CONTROLBOARDWRAPPER) << "Using removed parameter 'threadrate', use 'period' instead";
410  return false;
411  }
412 
413  // NOW, check for correct parameter, so if both are present we use the correct one
414  if(prop.check("period"))
415  {
416  if(!prop.find("period").isInt32())
417  {
418  yCError(CONTROLBOARDWRAPPER) << "'period' parameter is not an integer value";
419  return false;
420  }
421  period = prop.find("period").asInt32() / 1000.0;
422  if(period <= 0)
423  {
424  yCError(CONTROLBOARDWRAPPER) << "'period' parameter is not valid, read value is" << period;
425  return false;
426  }
427  }
428  else
429  {
430  yCDebug(CONTROLBOARDWRAPPER) << "'period' parameter missing, using default thread period = 20ms";
431  period = 0.02;
432  }
433 
434  // check if we need to create subdevice or if they are
435  // passed later on thorugh attachAll()
436  if(prop.check("subdevice"))
437  {
438  ownDevices=true;
439  prop.setMonitor(config.getMonitor());
440  if(! openAndAttachSubDevice(prop))
441  {
442  yCError(CONTROLBOARDWRAPPER, "Error while opening subdevice");
443  return false;
444  }
445  }
446  else
447  {
448  ownDevices=false;
449  if(!openDeferredAttach(prop))
450  return false;
451  }
452 
453  // using controlledJoints here will allocate more memory than required, but not so much.
454  rpcData.resize(device.subdevices.size(), controlledJoints, &device);
455 
456  /* This must be after the openAndAttachSubDevice() or openDeferredAttach() in order to have the correct number of controlledJoints,
457  but before the initialize_ROS and initialize_YARP */
458  if(!checkROSParams(config) )
459  {
460  yCError(CONTROLBOARDWRAPPER) << partName << " ROS parameter are not correct, check your configuration file";
461  return false;
462  }
463 
464  // call ROS node/topic initialization, if needed
465  if(!initialize_ROS() )
466  {
467  return false;
468  }
469 
470  // call YARP port initialization, if needed
471  if(!initialize_YARP(prop) )
472  {
473  yCError(CONTROLBOARDWRAPPER) << partName << "Something wrong when initting yarp ports";
474  return false;
475  }
476 
477  times.resize(controlledJoints);
478  ros_struct.name.resize(controlledJoints);
479  ros_struct.position.resize(controlledJoints);
480  ros_struct.velocity.resize(controlledJoints);
481  ros_struct.effort.resize(controlledJoints);
482 
483  // In case attach is not deferred and the controlboard already owns a valid device
484  // we can start the thread. Otherwise this will happen when attachAll is called
485  if (ownDevices)
486  {
487  PeriodicThread::setPeriod(period);
488  if (!PeriodicThread::start())
489  return false;
490  }
491  return true;
492 }
493 
494 
495 // Default usage
496 // Open the wrapper only, the attach method needs to be called before using it
497 bool ControlBoardWrapper::openDeferredAttach(Property& prop)
498 {
499  if (!prop.check("networks", "list of networks merged by this wrapper"))
500  {
501  yCError(CONTROLBOARDWRAPPER) << "List of networks to attach to was not found.";
502  return false;
503  }
504 
505  Bottle *nets=prop.find("networks").asList();
506  if(nets==nullptr)
507  {
508  yCError(CONTROLBOARDWRAPPER) << "Error parsing parameters: \"networks\" should be followed by a list";
509  return false;
510  }
511 
512  if (!prop.check("joints", "number of joints of the part"))
513  return false;
514 
515  controlledJoints=prop.find("joints").asInt32();
516 
517  int nsubdevices=nets->size();
518  device.lut.resize(controlledJoints);
519  device.subdevices.resize(nsubdevices);
520 
521  // configure the devices
522  int totalJ=0;
523  for(size_t k=0;k<nets->size();k++)
524  {
525  Bottle parameters;
526  int wBase;
527  int wTop;
528 
529  parameters=prop.findGroup(nets->get(k).asString());
530 
531  if(parameters.size()==2)
532  {
533  Bottle *bot=parameters.get(1).asList();
534  Bottle tmpBot;
535  if(bot==nullptr)
536  {
537  // probably data are not passed in the correct way, try to read them as a string.
538  std::string bString(parameters.get(1).asString());
539  tmpBot.fromString(bString);
540 
541  if(tmpBot.size() != 4)
542  {
543  yCError(CONTROLBOARDWRAPPER) << "Error: check network parameters in part description"
544  << "--> I was expecting "<<nets->get(k).asString() << " followed by a list of four integers in parenthesis"
545  << "Got: "<< parameters.toString();
546  return false;
547  }
548  else
549  {
550  bot = &tmpBot;
551  }
552  }
553 
554  // If I came here, bot is correct
555  wBase=bot->get(0).asInt32();
556  wTop=bot->get(1).asInt32();
557  base=bot->get(2).asInt32();
558  top=bot->get(3).asInt32();
559  }
560  else if (parameters.size()==5)
561  {
562  yCError(CONTROLBOARDWRAPPER) << "Parameter networks use deprecated syntax";
563  wBase=parameters.get(1).asInt32();
564  wTop=parameters.get(2).asInt32();
565  base=parameters.get(3).asInt32();
566  top=parameters.get(4).asInt32();
567  }
568  else
569  {
570  yCError(CONTROLBOARDWRAPPER) <<"Error: check network parameters in part description"
571  <<"--> I was expecting "<<nets->get(k).asString() << " followed by a list of four integers in parenthesis"
572  <<"Got: "<< parameters.toString();
573  return false;
574  }
575 
576  SubDevice *tmpDevice = device.getSubdevice(k);
577  if (!tmpDevice)
578  {
579  yCError(CONTROLBOARDWRAPPER) << "Get of subdevice returned null";
580  return false;
581  }
582 
583  tmpDevice->setVerbose(_verb);
584 
585  int axes=top-base+1;
586  if (!tmpDevice->configure(wBase, wTop, base, top, axes, nets->get(k).asString(), this))
587  {
588  yCError(CONTROLBOARDWRAPPER) <<"Configure of subdevice ret false";
589  return false;
590  }
591 
592  // Check input values are in range
593  if( (wBase < 0) || (wBase >= controlledJoints) )
594  {
595  yCError(CONTROLBOARDWRAPPER) << "Input configuration for device " << partName << "has a wrong attach map." << \
596  "First index " << wBase << "must be inside range from 0 to 'joints' ("<< controlledJoints << ")";
597  return false;
598  }
599 
600  if( (wTop < 0) || (wTop >= controlledJoints) )
601  {
602  yCError(CONTROLBOARDWRAPPER) << "Input configuration for device " << partName << "has a wrong attach map." << \
603  "Second index " << wTop << "must be inside range from 0 to 'joints' ("<< controlledJoints << ")";
604  return false;
605  }
606 
607  if(wBase > wTop)
608  {
609  yCError(CONTROLBOARDWRAPPER) << "Input configuration for device " << partName << "has a wrong attach map." << \
610  "First index " << wBase << "must be lower than second index " << wTop;
611  return false;
612  }
613 
614  for(int j=wBase, jInDev=base;j<=wTop;j++, jInDev++)
615  {
616  device.lut[j].deviceEntry=k;
617  device.lut[j].offset=j-wBase;
618  device.lut[j].jointIndexInDev=jInDev;
619  }
620 
621  totalJ+=axes;
622  }
623 
624  if (totalJ!=controlledJoints)
625  {
626  yCError(CONTROLBOARDWRAPPER) <<"Error total number of mapped joints ("<< totalJ <<") does not correspond to part joints (" << controlledJoints << ")";
627  return false;
628  }
629  return true;
630 }
631 
632 // For the simulator, if a subdevice parameter is given to the wrapper, it will
633 // open it and attach to immediately.
634 bool ControlBoardWrapper::openAndAttachSubDevice(Property& prop)
635 {
636  Property p;
637  subDeviceOwned = new PolyDriver;
638  p.fromString(prop.toString());
639 
640  std::string subdevice = prop.find("subdevice").asString();
641  p.setMonitor(prop.getMonitor(), subdevice.c_str()); // pass on any monitoring
642  p.unput("device");
643  p.put("device", subdevice); // subdevice was already checked before
644 
645  // if errors occurred during open, quit here.
646  yCDebug(CONTROLBOARDWRAPPER, "opening subdevice");
647  subDeviceOwned->open(p);
648 
649  if (!subDeviceOwned->isValid())
650  {
651  yCError(CONTROLBOARDWRAPPER, "opening subdevice... FAILED");
652  return false;
653  }
654 
655  yarp::dev::IEncoders * iencs = nullptr;
656 
657  subDeviceOwned->view(iencs);
658 
659  if (iencs == nullptr)
660  {
661  yCError(CONTROLBOARDWRAPPER, "Opening IEncoders interface of subdevice... FAILED");
662  return false;
663  }
664 
665  bool getAx = iencs->getAxes(&controlledJoints);
666 
667  if (!getAx)
668  {
669  yCError(CONTROLBOARDWRAPPER, "Calling getAxes of subdevice... FAILED");
670  return false;
671  }
672  yCDebug(CONTROLBOARDWRAPPER, "Joints parameter is %d", controlledJoints);
673 
674 
675  device.lut.resize(controlledJoints);
676  device.subdevices.resize(1);
677 
678  // configure the device
679  base = 0;
680  top = controlledJoints-1;
681 
682  int wbase = base;
683  int wtop = top;
684  SubDevice *tmpDevice=device.getSubdevice(0);
685  tmpDevice->setVerbose(_verb);
686 
687  std::string subDevName ((partName + "_" + subdevice));
688  if (!tmpDevice->configure(wbase, wtop, base, top, controlledJoints, subDevName, this) )
689  {
690  yCError(CONTROLBOARDWRAPPER) << "Configure of subdevice ret false";
691  return false;
692  }
693 
694  for(int j=0; j<controlledJoints; j++)
695  {
696  device.lut[j].deviceEntry = 0;
697  device.lut[j].offset = j;
698  }
699 
700 
701  if (!device.subdevices[0].attach(subDeviceOwned, subDevName))
702  return false;
703 
704  // initialization.
705  RPC_parser.initialize();
706  updateAxisName();
707  calculateMaxNumOfJointsInDevices();
708  return true;
709 }
710 
711 void ControlBoardWrapper::calculateMaxNumOfJointsInDevices()
712 {
713  device.maxNumOfJointsInDevices = 0;
714 
715  for(unsigned int d=0; d<device.subdevices.size(); d++)
716  {
717  SubDevice *p = device.getSubdevice(d);
718  if(p->totalAxis > device.maxNumOfJointsInDevices)
720  }
721 }
722 
723 bool ControlBoardWrapper::updateAxisName()
724 {
725  // If attached device has axisName update the internal values, otherwise keep the on from wrapper
726  // config file, if any.
727  // IMPORTANT!! This function has to be called BEFORE the thread starts, because if ROS is enabled,
728  // the name has to be correct right from the first message!!
729 
730  // FOR THE FUTURE: this double version will be dropped because it'll create confusion. Only the names
731  // from the motionControl device will be considered good
732 
733  // no need to update this variable if we are not using ROS. Yarp RPC will always call the sudevice.
734  if(useROS == ROS_disabled )
735  return true;
736 
737  std::string tmp;
738  // I need a temporary vector because if I'm wrapping more than one subdevice, and one of them
739  // does not have the axesName, then I'd stick with the old names from wrpper config file, if any.
740  vector<string> tmpVect;
741  bool ret = true;
742 
743  tmpVect.clear();
744  for(int i=0; i < controlledJoints; i++)
745  {
746  if( (ret = getAxisName(i, tmp) && ret) )
747  {
748  std::string tmp2(tmp);
749  tmpVect.push_back(tmp2);
750  }
751  }
752 
753  if(ret)
754  {
755  if(jointNames.size() != 0)
756  {
757  yCWarning(CONTROLBOARDWRAPPER) << "Found 2 instance of jointNames parameter: one in the wrapper [ROS] group and another one in the subdevice, the latter one will be used.";
758  std::string fullNames;
759  for(int i=0; i < controlledJoints; i++) fullNames.append(tmpVect[i]);
760  }
761 
762  jointNames.clear();
763  jointNames = tmpVect;
764  }
765  else
766  {
767  if(jointNames.size() == 0)
768  {
769  yCError(CONTROLBOARDWRAPPER) << "Joint names were not found! they are mandatory when using ROS topic";
770  return false;
771  }
772  else
773  {
774  yCWarning(CONTROLBOARDWRAPPER) << "\n" <<
775  "************************************************************************************************** \n" <<
776  "* Joint names for ROS topic were found in the [ROS] group in the wrapper config file for\n" <<
777  "* '" << partName << "' device.\n" <<
778  "* They should be in the MotionControl device(s) instead. Please update the config files.\n" <<
779  "**************************************************************************************************";
780  }
781  }
782  return true;
783 }
784 
785 
787 {
788  //check if we already instantiated a subdevice previously
789  if (ownDevices)
790  return false;
791 
792  for(int p=0;p<polylist.size();p++)
793  {
794  // look if we have to attach to a calibrator
795  std::string tmpKey=polylist[p]->key;
796  if(tmpKey == "Calibrator" || tmpKey == "calibrator")
797  {
798  // Set the IRemoteCalibrator interface, the wrapper must point to the calibrato rdevice
799  yarp::dev::IRemoteCalibrator *calibrator;
800  polylist[p]->poly->view(calibrator);
801 
802  IRemoteCalibrator::setCalibratorDevice(calibrator);
803  continue;
804  }
805 
806  // find appropriate entry in list of subdevices and attach
807  unsigned int k=0;
808  for(k=0; k<device.subdevices.size(); k++)
809  {
810  if (device.subdevices[k].id==tmpKey)
811  {
812  if (!device.subdevices[k].attach(polylist[p]->poly, tmpKey))
813  {
814  yCError(CONTROLBOARDWRAPPER, "Attach to subdevice %s failed", polylist[p]->key.c_str());
815  return false;
816  }
817  }
818  }
819  }
820 
821  //check if all devices are attached to the driver
822  bool ready=true;
823  for(auto& subdevice : device.subdevices)
824  {
825  if (!subdevice.isAttached())
826  {
827  yCError(CONTROLBOARDWRAPPER, "Device %s was not found in the list passed to attachAll", subdevice.id.c_str());
828  ready=false;
829  }
830  }
831 
832  if (!ready)
833  {
834  yCError(CONTROLBOARDWRAPPER, "AttachAll failed, some subdevice was not found or its attach failed");
835  stringstream ss;
836  for(int p=0;p<polylist.size();p++)
837  {
838  ss << polylist[p]->key.c_str() << " ";
839  }
840  yCError(CONTROLBOARDWRAPPER, "List of devices keys passed to attachAll: %s", ss.str().c_str());
841  return false;
842  }
843 
844  // initialization.
845  RPC_parser.initialize();
846 
847  updateAxisName();
848  calculateMaxNumOfJointsInDevices();
849  PeriodicThread::setPeriod(period);
850  return PeriodicThread::start();
851 }
852 
854 {
855  //check if we already instantiated a subdevice previously
856  if (ownDevices)
857  return false;
858 
861 
862  int devices=device.subdevices.size();
863 
864  for(int k=0;k<devices;k++) {
865  SubDevice* sub = device.getSubdevice(k);
866  if (sub) sub->detach();
867  }
868 
869  IRemoteCalibrator::releaseCalibratorDevice();
870  return true;
871 }
872 
874 {
875  // check we are not overflowing with input messages
876  if(inputStreamingPort.getPendingReads() >= 20)
877  {
878  yCWarning(CONTROLBOARDWRAPPER) << "Number of streaming intput messages to be read is " << inputStreamingPort.getPendingReads() << " and can overflow";
879  }
880 
881  // Small optimization: Avoid to call getEncoders twice, one for YARP port
882  // and again for ROS topic.
883  //
884  // Calling getStuff here on ros_struct because it is a class member, hence
885  // always available. In the other side, to have the yarp struct to write into
886  // it will be rewuired to call port.prepare, that it is something I should
887  // not do if the wrapper is in ROS_only configuration.
888 
889  bool positionsOk = getEncodersTimed(ros_struct.position.data(), times.data());
890  bool speedsOk = getEncoderSpeeds(ros_struct.velocity.data());
891  bool torqueOk = getTorques(ros_struct.effort.data());
892 
893  // Update the port envelope time by averaging all timestamps
894  timeMutex.lock();
895  time.update(std::accumulate(times.begin(), times.end(), 0.0) / controlledJoints);
896  yarp::os::Stamp averageTime = time;
897  timeMutex.unlock();
898 
899  if(useROS != ROS_only)
900  {
901  // handle stateExt first
902  jointData &yarp_struct = extendedOutputState_buffer.get();
903 
904  yarp_struct.jointPosition.resize(controlledJoints);
905  yarp_struct.jointVelocity.resize(controlledJoints);
906  yarp_struct.jointAcceleration.resize(controlledJoints);
907  yarp_struct.motorPosition.resize(controlledJoints);
908  yarp_struct.motorVelocity.resize(controlledJoints);
909  yarp_struct.motorAcceleration.resize(controlledJoints);
910  yarp_struct.torque.resize(controlledJoints);
911  yarp_struct.pwmDutycycle.resize(controlledJoints);
912  yarp_struct.current.resize(controlledJoints);
913  yarp_struct.controlMode.resize(controlledJoints);
914  yarp_struct.interactionMode.resize(controlledJoints);
915 
916  // Get already stored data from before. This is to avoid a double call to HW device,
917  // which may require more time. //
918  yarp_struct.jointPosition_isValid = positionsOk;
919  std::copy(ros_struct.position.begin(), ros_struct.position.end(), yarp_struct.jointPosition.begin());
920 
921  yarp_struct.jointVelocity_isValid = speedsOk;
922  std::copy(ros_struct.velocity.begin(), ros_struct.velocity.end(), yarp_struct.jointVelocity.begin());
923 
924  yarp_struct.torque_isValid = torqueOk;
925  std::copy(ros_struct.effort.begin(), ros_struct.effort.end(), yarp_struct.torque.begin());
926 
927  // Get remaining data from HW
929  yarp_struct.motorPosition_isValid = getMotorEncoders(yarp_struct.motorPosition.data());
930  yarp_struct.motorVelocity_isValid = getMotorEncoderSpeeds(yarp_struct.motorVelocity.data());
932  yarp_struct.pwmDutycycle_isValid = getDutyCycles(yarp_struct.pwmDutycycle.data());
933  yarp_struct.current_isValid = getCurrents(yarp_struct.current.data());
934  yarp_struct.controlMode_isValid = getControlModes(yarp_struct.controlMode.data());
936 
937  extendedOutputStatePort.setEnvelope(averageTime);
938  extendedOutputState_buffer.write();
939 
940  // handle state:o
941  yarp::sig::Vector& v = outputPositionStatePort.prepare();
942  v.resize(controlledJoints);
943  std::copy(yarp_struct.jointPosition.begin(), yarp_struct.jointPosition.end(), v.begin());
944 
945  outputPositionStatePort.setEnvelope(averageTime);
946  outputPositionStatePort.write();
947  }
948 
949  if(useROS != ROS_disabled)
950  {
951  // Data from HW have been gathered few lines before
952  JointTypeEnum jType;
953  for(int i=0; i< controlledJoints; i++)
954  {
955  getJointType(i, jType);
956  if(jType == VOCAB_JOINTTYPE_REVOLUTE)
957  {
958  ros_struct.position[i] = convertDegreesToRadians(ros_struct.position[i]);
959  ros_struct.velocity[i] = convertDegreesToRadians(ros_struct.velocity[i]);
960  }
961  }
962 
963  ros_struct.name=jointNames;
964 
965  ros_struct.header.seq = rosMsgCounter++;
966  ros_struct.header.stamp = averageTime.getTime();
967 
968  rosPublisherPort.write(ros_struct);
969  }
970 }
971 
972 //
973 // IPid Interface
974 //
975 bool ControlBoardWrapper::setPid(const PidControlTypeEnum& pidtype, int j, const Pid &p)
976 {
977  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
978  int subIndex=device.lut[j].deviceEntry;
979 
980  SubDevice *s=device.getSubdevice(subIndex);
981  if (!s)
982  return false;
983 
984  if (s->pid)
985  {
986  return s->pid->setPid(pidtype, off+s->base, p);
987  }
988  return false;
989 }
990 
991 bool ControlBoardWrapper::setPids(const PidControlTypeEnum& pidtype, const Pid *ps)
992 {
993  bool ret=true;
994 
995  for(int l=0;l<controlledJoints;l++)
996  {
997  int off=device.lut[l].offset;
998  int subIndex=device.lut[l].deviceEntry;
999 
1000  SubDevice *p=device.getSubdevice(subIndex);
1001  if (!p)
1002  return false;
1003 
1004  if (p->pid)
1005  {
1006  ret=ret&&p->pid->setPid(pidtype, off+p->base, ps[l]);
1007  }
1008  else
1009  ret=false;
1010  }
1011  return ret;
1012 }
1013 
1014 bool ControlBoardWrapper::setPidReference(const PidControlTypeEnum& pidtype, int j, double ref)
1015 {
1016  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1017  int subIndex=device.lut[j].deviceEntry;
1018 
1019  SubDevice *p=device.getSubdevice(subIndex);
1020  if (!p)
1021  return false;
1022 
1023  if (p->pid)
1024  {
1025  return p->pid->setPidReference(pidtype, off+p->base, ref);
1026  }
1027  return false;
1028 }
1029 
1030 bool ControlBoardWrapper::setPidReferences(const PidControlTypeEnum& pidtype, const double *refs)
1031 {
1032  bool ret=true;
1033 
1034  for(int l=0;l<controlledJoints;l++)
1035  {
1036  int off=device.lut[l].offset;
1037  int subIndex=device.lut[l].deviceEntry;
1038 
1039  SubDevice *p=device.getSubdevice(subIndex);
1040  if (!p)
1041  return false;
1042 
1043  if (p->pid)
1044  {
1045  ret=ret&&p->pid->setPidReference(pidtype, off+p->base, refs[l]);
1046  }
1047  else
1048  ret=false;
1049  }
1050  return ret;
1051 }
1052 
1053 bool ControlBoardWrapper::setPidErrorLimit(const PidControlTypeEnum& pidtype, int j, double limit)
1054 {
1055  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1056  int subIndex=device.lut[j].deviceEntry;
1057 
1058  SubDevice *p=device.getSubdevice(subIndex);
1059  if (!p)
1060  return false;
1061 
1062  if (p->pid)
1063  {
1064  return p->pid->setPidErrorLimit(pidtype, off+p->base, limit);
1065  }
1066  return false;
1067 }
1068 
1069 bool ControlBoardWrapper::setPidErrorLimits(const PidControlTypeEnum& pidtype, const double *limits)
1070 {
1071  bool ret=true;
1072 
1073  for(int l=0;l<controlledJoints;l++)
1074  {
1075  int off=device.lut[l].offset;
1076  int subIndex=device.lut[l].deviceEntry;
1077 
1078  SubDevice *p=device.getSubdevice(subIndex);
1079  if (!p)
1080  return false;
1081 
1082  if (p->pid)
1083  {
1084  ret=ret&&p->pid->setPidErrorLimit(pidtype, off+p->base, limits[l]);
1085  }
1086  else
1087  ret=false;
1088  }
1089  return ret;
1090 }
1091 
1092 bool ControlBoardWrapper::getPidError(const PidControlTypeEnum& pidtype, int j, double *err)
1093 {
1094  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1095  int subIndex=device.lut[j].deviceEntry;
1096 
1097  SubDevice *p=device.getSubdevice(subIndex);
1098  if (!p)
1099  return false;
1100 
1101  if (p->pid)
1102  {
1103  return p->pid->getPidError(pidtype, off+p->base, err);
1104  }
1105  *err = 0.0;
1106  return false;
1107 }
1108 
1109 bool ControlBoardWrapper::getPidErrors(const PidControlTypeEnum& pidtype, double *errs)
1110 {
1111  auto* errors = new double [device.maxNumOfJointsInDevices];
1112 
1113  bool ret = true;
1114  for(unsigned int d=0; d<device.subdevices.size(); d++)
1115  {
1116  SubDevice *p=device.getSubdevice(d);
1117  if(!p)
1118  {
1119  ret = false;
1120  break;
1121  }
1122  if( (p->pid) &&(ret = p->pid->getPidErrors(pidtype, errors)) )
1123  {
1124  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
1125  {
1126  errs[juser] = errors[jdevice];
1127  }
1128  }
1129  else
1130  {
1131  printError("getPidErrors", p->id, ret);
1132  ret = false;
1133  break;
1134  }
1135  }
1136 
1137  delete[] errors;
1138  return ret;
1139 }
1140 
1141 bool ControlBoardWrapper::getPidOutput(const PidControlTypeEnum& pidtype, int j, double *out)
1142 {
1143  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1144  int subIndex=device.lut[j].deviceEntry;
1145 
1146  SubDevice *p=device.getSubdevice(subIndex);
1147  if (!p)
1148  return false;
1149 
1150  if (p->pid)
1151  {
1152  return p->pid->getPidOutput(pidtype, off+p->base, out);
1153  }
1154  *out=0.0;
1155  return false;
1156 }
1157 
1158 bool ControlBoardWrapper::getPidOutputs(const PidControlTypeEnum& pidtype, double *outs)
1159 {
1160  auto* outputs = new double[device.maxNumOfJointsInDevices];
1161  bool ret = true;
1162  for(unsigned int d=0; d<device.subdevices.size(); d++)
1163  {
1164  SubDevice *p=device.getSubdevice(d);
1165  if(!p)
1166  {
1167  ret = false;
1168  break;
1169  }
1170 
1171  if( (p->pid) &&(ret = p->pid->getPidOutputs(pidtype, outputs)))
1172  {
1173  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
1174  {
1175  outs[juser] = outputs[jdevice];
1176  }
1177  }
1178  else
1179  {
1180  printError("getPidOutouts", p->id, ret);
1181  ret = false;
1182  break;
1183  }
1184  }
1185 
1186  delete [] outputs;
1187  return ret;
1188 }
1189 
1190 bool ControlBoardWrapper::setPidOffset(const PidControlTypeEnum& pidtype, int j, double v)
1191 {
1192  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1193  int subIndex=device.lut[j].deviceEntry;
1194 
1195  SubDevice *p=device.getSubdevice(subIndex);
1196  if (!p)
1197  return false;
1198 
1199  if (p->pid)
1200  {
1201  return p->pid->setPidOffset(pidtype, off+p->base, v);
1202  }
1203  return false;
1204 }
1205 
1206 bool ControlBoardWrapper::getPid(const PidControlTypeEnum& pidtype, int j, Pid *p)
1207 {
1208 //#warning "check for max number of joints!?!?!"
1209  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1210  int subIndex=device.lut[j].deviceEntry;
1211 
1212  SubDevice *s=device.getSubdevice(subIndex);
1213  if (!s)
1214  return false;
1215 
1216  if (s->pid)
1217  {
1218  return s->pid->getPid(pidtype, off+s->base, p);
1219  }
1220  return false;
1221 }
1222 
1224 {
1225  Pid *pids_device = new Pid[device.maxNumOfJointsInDevices];
1226  bool ret = true;
1227  for(unsigned int d=0; d<device.subdevices.size(); d++)
1228  {
1229  SubDevice *p=device.getSubdevice(d);
1230  if(!p)
1231  {
1232  ret = false;
1233  break;
1234  }
1235 
1236  if( (p->pid) &&(ret = p->pid->getPids(pidtype, pids_device)))
1237  {
1238  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
1239  {
1240  pids[juser] = pids_device[jdevice];
1241  }
1242  }
1243  else
1244  {
1245  printError("getPids", p->id, ret);
1246  ret = false;
1247  break;
1248  }
1249  }
1250 
1251  delete[] pids_device;
1252  return ret;
1253 }
1254 
1255 bool ControlBoardWrapper::getPidReference(const PidControlTypeEnum& pidtype, int j, double *ref) {
1256  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1257  int subIndex=device.lut[j].deviceEntry;
1258 
1259  SubDevice *p=device.getSubdevice(subIndex);
1260  if (!p)
1261  return false;
1262  if (p->pid)
1263  {
1264  return p->pid->getPidReference(pidtype, off+p->base, ref);
1265  }
1266  return false;
1267 }
1268 
1270 {
1271  auto* references = new double[device.maxNumOfJointsInDevices];
1272  bool ret = true;
1273  for(unsigned int d=0; d<device.subdevices.size(); d++)
1274  {
1275  SubDevice *p=device.getSubdevice(d);
1276  if(!p)
1277  {
1278  ret = false;
1279  break;
1280  }
1281 
1282  if( (p->pid) &&(ret = p->pid->getPidReferences(pidtype, references)))
1283  {
1284  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
1285  {
1286  refs[juser] = references[jdevice];
1287  }
1288  }
1289  else
1290  {
1291  printError("getPidReferences", p->id, ret);
1292  ret = false;
1293  break;
1294  }
1295  }
1296 
1297  delete [] references;
1298  return ret;
1299 }
1300 
1301 bool ControlBoardWrapper::getPidErrorLimit(const PidControlTypeEnum& pidtype, int j, double *limit) {
1302  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1303  int subIndex=device.lut[j].deviceEntry;
1304 
1305  SubDevice *p=device.getSubdevice(subIndex);
1306  if (!p)
1307  return false;
1308 
1309  if (p->pid)
1310  {
1311  return p->pid->getPidErrorLimit(pidtype, off+p->base, limit);
1312  }
1313  return false;
1314 }
1315 
1317 {
1318  auto* lims = new double[device.maxNumOfJointsInDevices];
1319  bool ret = true;
1320  for(unsigned int d=0; d<device.subdevices.size(); d++)
1321  {
1322  SubDevice *p=device.getSubdevice(d);
1323  if(!p)
1324  {
1325  ret = false;
1326  break;
1327  }
1328 
1329  if( (p->pid) &&(ret = p->pid->getPidErrorLimits(pidtype, lims)))
1330  {
1331  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
1332  {
1333  limits[juser] = lims[jdevice];
1334  }
1335  }
1336  else
1337  {
1338  printError("getPidErrorLimits", p->id, ret);
1339  ret = false;
1340  break;
1341  }
1342  }
1343 
1344  delete [] lims;
1345  return ret;
1346 }
1347 
1349  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1350  int subIndex=device.lut[j].deviceEntry;
1351 
1352  SubDevice *p=device.getSubdevice(subIndex);
1353  if (!p)
1354  return false;
1355 
1356  if (p->pid)
1357  {
1358  return p->pid->resetPid(pidtype, off+p->base);
1359  }
1360  return false;
1361 }
1362 
1364  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1365  int subIndex=device.lut[j].deviceEntry;
1366 
1367  SubDevice *p=device.getSubdevice(subIndex);
1368  if (!p)
1369  return false;
1370 
1371  if (p->pid)
1372  {
1373  return p->pid->disablePid(pidtype, off+p->base);
1374  }
1375  return false;
1376 }
1377 
1379  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1380  int subIndex=device.lut[j].deviceEntry;
1381 
1382  SubDevice *p=device.getSubdevice(subIndex);
1383  if (!p)
1384  return false;
1385 
1386  if (p->pid)
1387  {
1388  return p->pid->enablePid(pidtype, off+p->base);
1389  }
1390  return false;
1391 }
1392 
1393 bool ControlBoardWrapper::isPidEnabled(const PidControlTypeEnum& pidtype, int j, bool* enabled)
1394 {
1395  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1396  int subIndex=device.lut[j].deviceEntry;
1397 
1398  SubDevice *p=device.getSubdevice(subIndex);
1399  if (!p)
1400  return false;
1401 
1402  if(p->pid)
1403  return p->pid->isPidEnabled(pidtype, off+p->base, enabled);
1404 
1405  return false;
1406 }
1407 
1408 //
1409 // IPOSITIONCONTROL
1410 //
1411 /* IPositionControl */
1412 
1420  *ax=controlledJoints;
1421  return true;
1422 }
1423 
1430 bool ControlBoardWrapper::positionMove(int j, double ref) {
1431  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1432  int subIndex=device.lut[j].deviceEntry;
1433 
1434  SubDevice *p=device.getSubdevice(subIndex);
1435  if (!p)
1436  return false;
1437 
1438  if (p->pos)
1439  {
1440  return p->pos->positionMove(off+p->base, ref);
1441  }
1442 
1443  return false;
1444 }
1445 
1450 bool ControlBoardWrapper::positionMove(const double *refs)
1451 {
1452  bool ret = true;
1453  int j_wrap = 0; // index of the wrapper joint
1454 
1455  int nDev = device.subdevices.size();
1456  for(int subDev_idx=0; subDev_idx < nDev; subDev_idx++)
1457  {
1458  int subIndex=device.lut[j_wrap].deviceEntry;
1459  SubDevice *p=device.getSubdevice(subIndex);
1460 
1461  if (!p)
1462  {
1463  return false;
1464  }
1465 
1466  int wrapped_joints=(p->top - p->base) + 1;
1467  int *joints = new int[wrapped_joints];
1468 
1469  if(p->pos)
1470  {
1471  // versione comandi su subset di giunti
1472  for(int j_dev = 0; j_dev < wrapped_joints; j_dev++)
1473  {
1474  joints[j_dev] = p->base + j_dev; // for all joints is equivalent to add offset term
1475  }
1476 
1477  ret = ret && p->pos->positionMove(wrapped_joints, joints, &refs[j_wrap]);
1478  j_wrap+=wrapped_joints;
1479  }
1480  else
1481  {
1482  ret=false;
1483  }
1484 
1485  if(joints!=nullptr)
1486  { delete [] joints;
1487  joints = nullptr;}
1488  }
1489 
1490  return ret;
1491 }
1492 
1498 bool ControlBoardWrapper::positionMove(const int n_joints, const int *joints, const double *refs)
1499 {
1500  bool ret = true;
1501 
1502  rpcDataMutex.lock();
1503  //Reset subdev_jointsVectorLen vector
1504  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
1505 
1506  // Create a map of joints for each subDevice
1507  int subIndex = 0;
1508  for(int j=0; j<n_joints; j++)
1509  {
1510  subIndex = device.lut[joints[j]].deviceEntry;
1511  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[joints[j]].offset + rpcData.subdevices_p[subIndex]->base;
1512  rpcData.values[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = refs[j];
1513  rpcData.subdev_jointsVectorLen[subIndex]++;
1514  }
1515 
1516  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
1517  {
1518  if(rpcData.subdevices_p[subIndex]->pos)
1519  {
1520  ret= ret && rpcData.subdevices_p[subIndex]->pos->positionMove(rpcData.subdev_jointsVectorLen[subIndex],
1521  rpcData.jointNumbers[subIndex],
1522  rpcData.values[subIndex]);
1523  }
1524  else
1525  {
1526  ret=false;
1527  }
1528  }
1529  rpcDataMutex.unlock();
1530  return ret;
1531 }
1532 
1533 bool ControlBoardWrapper::getTargetPosition(const int j, double* ref)
1534 {
1535  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1536  int subIndex=device.lut[j].deviceEntry;
1537 
1538  SubDevice *p=device.getSubdevice(subIndex);
1539 
1540  if (!p)
1541  return false;
1542 
1543  if (p->pos)
1544  {
1545  bool ret = p->pos->getTargetPosition(off+p->base, ref);
1546  return ret;
1547  }
1548  *ref=0;
1549  return false;
1550 }
1551 
1552 
1559 {
1560  auto* targets = new double[device.maxNumOfJointsInDevices];
1561  bool ret = true;
1562  for(unsigned int d=0; d<device.subdevices.size(); d++)
1563  {
1564  SubDevice *p=device.getSubdevice(d);
1565  if(!p)
1566  {
1567  ret = false;
1568  break;
1569  }
1570 
1571  if( (p->pos) &&(ret = p->pos->getTargetPositions(targets)))
1572  {
1573  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
1574  {
1575  spds[juser] = targets[jdevice];
1576  }
1577  }
1578  else
1579  {
1580  printError("getTargetPositions", p->id, ret);
1581  ret = false;
1582  break;
1583  }
1584  }
1585 
1586  delete [] targets;
1587  return ret;
1588 }
1589 
1590 
1591 bool ControlBoardWrapper::getTargetPositions(const int n_joints, const int *joints, double *targets)
1592 {
1593  bool ret = true;
1594 
1595  rpcDataMutex.lock();
1596  //Reset subdev_jointsVectorLen vector
1597  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
1598 
1599  // Create a map of joints for each subDevice
1600  int subIndex = 0;
1601  for(int j=0; j<n_joints; j++)
1602  {
1603  subIndex = device.lut[joints[j]].deviceEntry;
1604  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[joints[j]].offset + rpcData.subdevices_p[subIndex]->base;
1605  rpcData.subdev_jointsVectorLen[subIndex]++;
1606  }
1607 
1608  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
1609  {
1610  if(rpcData.subdevices_p[subIndex]->pos)
1611  {
1612  ret= ret && rpcData.subdevices_p[subIndex]->pos->getTargetPositions( rpcData.subdev_jointsVectorLen[subIndex],
1613  rpcData.jointNumbers[subIndex],
1614  rpcData.values[subIndex]);
1615  }
1616  }
1617 
1618  if(ret)
1619  {
1620  // ReMix values by user expectations
1621  for(int i=0; i<rpcData.deviceNum; i++)
1622  rpcData.subdev_jointsVectorLen[i]=0; // reset tmp index
1623 
1624  // fill the output vector
1625  for(int j=0; j<n_joints; j++)
1626  {
1627  subIndex = device.lut[joints[j]].deviceEntry;
1628  targets[j] = rpcData.values[subIndex][rpcData.subdev_jointsVectorLen[subIndex]];
1629  rpcData.subdev_jointsVectorLen[subIndex]++;
1630  }
1631  }
1632  else
1633  {
1634  for(int j=0; j<n_joints; j++)
1635  {
1636  targets[j] = 0;
1637  }
1638  }
1639  rpcDataMutex.unlock();
1640  return ret;
1641 }
1642 
1649 bool ControlBoardWrapper::relativeMove(int j, double delta) {
1650  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1651  int subIndex=device.lut[j].deviceEntry;
1652 
1653  SubDevice *p=device.getSubdevice(subIndex);
1654  if (!p)
1655  return false;
1656 
1657  if (p->pos)
1658  {
1659  return p->pos->relativeMove(off+p->base, delta);
1660  }
1661 
1662  return false;
1663 }
1664 
1669 bool ControlBoardWrapper::relativeMove(const double *deltas) {
1670  bool ret=true;
1671 
1672  for(int l=0;l<controlledJoints;l++)
1673  {
1674  int off=device.lut[l].offset;
1675  int subIndex=device.lut[l].deviceEntry;
1676 
1677  SubDevice *p=device.getSubdevice(subIndex);
1678  if (!p)
1679  return false;
1680 
1681  if (p->pos)
1682  {
1683  ret=ret&&p->pos->relativeMove(off+p->base, deltas[l]);
1684  }
1685  else
1686  ret=false;
1687  }
1688  return ret;
1689 }
1690 
1696 bool ControlBoardWrapper::relativeMove(const int n_joints, const int *joints, const double *deltas)
1697 {
1698  bool ret = true;
1699 
1700  rpcDataMutex.lock();
1701  //Reset subdev_jointsVectorLen vector
1702  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
1703 
1704  // Create a map of joints for each subDevice
1705  int subIndex = 0;
1706  for(int j=0; j<n_joints; j++)
1707  {
1708  subIndex = device.lut[joints[j]].deviceEntry;
1709  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[joints[j]].offset + rpcData.subdevices_p[subIndex]->base;
1710  rpcData.values[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = deltas[j];
1711  rpcData.subdev_jointsVectorLen[subIndex]++;
1712  }
1713 
1714  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
1715  {
1716  if(rpcData.subdevices_p[subIndex]->pos)
1717  {
1718  ret= ret && rpcData.subdevices_p[subIndex]->pos->relativeMove(rpcData.subdev_jointsVectorLen[subIndex],
1719  rpcData.jointNumbers[subIndex],
1720  rpcData.values[subIndex]);
1721  }
1722  else
1723  {
1724  ret=false;
1725  }
1726  }
1727  rpcDataMutex.unlock();
1728  return ret;
1729 }
1730 
1737 bool ControlBoardWrapper::checkMotionDone(int j, bool *flag) {
1738  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1739  int subIndex=device.lut[j].deviceEntry;
1740 
1741  SubDevice *p=device.getSubdevice(subIndex);
1742 
1743  if (!p)
1744  return false;
1745 
1746  if (p->pos)
1747  {
1748  return p->pos->checkMotionDone(off+p->base, flag);
1749  }
1750 
1751  return false;
1752 }
1753 
1760 {
1761  bool ret = true;
1762 
1763  rpcDataMutex.lock();
1764  //Reset subdev_jointsVectorLen vector
1765  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
1766 
1767  // Create a map of joints for each subDevice
1768  // In this case the "all joint version" of checkMotionDone(bool *flag) cannot be
1769  // called because the return value is an 'and' of all joints.
1770  // Therefore only the corret joints must be evaluated.
1771 
1772  int subIndex = 0;
1773  for(int j=0; j<controlledJoints; j++)
1774  {
1775  subIndex = device.lut[j].deviceEntry;
1776  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[j].offset + rpcData.subdevices_p[subIndex]->base;
1777  rpcData.subdev_jointsVectorLen[subIndex]++;
1778  }
1779 
1780  bool tmp_subdeviceDone = true;
1781  bool tmp_deviceDone = true;
1782 
1783  // for each subdevice wrapped call checkmotiondone only on interested joints
1784  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
1785  {
1786  if(rpcData.subdevices_p[subIndex]->pos)
1787  {
1788  ret= ret && rpcData.subdevices_p[subIndex]->pos->checkMotionDone( rpcData.subdev_jointsVectorLen[subIndex],
1789  rpcData.jointNumbers[subIndex],
1790  &tmp_subdeviceDone);
1791  tmp_deviceDone &= tmp_subdeviceDone;
1792  }
1793  }
1794  rpcDataMutex.unlock();
1795 
1796  // return a single value to the caller
1797  *flag = tmp_deviceDone;
1798  return ret;
1799 }
1800 
1801 
1808 bool ControlBoardWrapper::checkMotionDone(const int n_joints, const int *joints, bool *flags)
1809 {
1810  bool ret = true;
1811  bool tmp = true;
1812  bool XFlags = true;
1813 
1814  rpcDataMutex.lock();
1815  //Reset subdev_jointsVectorLen vector
1816  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
1817 
1818  // Create a map of joints for each subDevice
1819  int subIndex = 0;
1820  for(int j=0; j<n_joints; j++)
1821  {
1822  subIndex = device.lut[joints[j]].deviceEntry;
1823  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[joints[j]].offset + rpcData.subdevices_p[subIndex]->base;
1824  rpcData.subdev_jointsVectorLen[subIndex]++;
1825  }
1826 
1827  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
1828  {
1829  if(rpcData.subdevices_p[subIndex]->pos)
1830  {
1831  ret= ret && rpcData.subdevices_p[subIndex]->pos->checkMotionDone(rpcData.subdev_jointsVectorLen[subIndex],
1832  rpcData.jointNumbers[subIndex],
1833  &XFlags);
1834  tmp = tmp && XFlags;
1835  }
1836  else
1837  {
1838  ret=false;
1839  }
1840  }
1841  if(ret)
1842  *flags = tmp;
1843  else
1844  *flags = false;
1845  rpcDataMutex.unlock();
1846  return ret;
1847 }
1848 
1855 bool ControlBoardWrapper::setRefSpeed(int j, double sp) {
1856  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1857  int subIndex=device.lut[j].deviceEntry;
1858 
1859  SubDevice *p=device.getSubdevice(subIndex);
1860  if (!p)
1861  return false;
1862 
1863  if (p->pos)
1864  {
1865  return p->pos->setRefSpeed(off+p->base, sp);
1866  }
1867  return false;
1868 }
1869 
1875 bool ControlBoardWrapper::setRefSpeeds(const double *spds)
1876 {
1877  bool ret = true;
1878  int j_wrap = 0; // index of the wrapper joint
1879 
1880  for(unsigned int subDev_idx=0; subDev_idx < device.subdevices.size(); subDev_idx++)
1881  {
1882  SubDevice *p=device.getSubdevice(subDev_idx);
1883 
1884  if(!p)
1885  return false;
1886 
1887  int wrapped_joints=(p->top - p->base) + 1;
1888  int *joints = new int[wrapped_joints];
1889 
1890  if(p->pos)
1891  {
1892  // verione comandi su subset di giunti
1893  for(int j_dev = 0; j_dev < wrapped_joints; j_dev++)
1894  {
1895  joints[j_dev] = p->base + j_dev;
1896  }
1897 
1898  ret = ret && p->pos->setRefSpeeds(wrapped_joints, joints, &spds[j_wrap]);
1899  j_wrap += wrapped_joints;
1900  }
1901  else
1902  {
1903  ret=false;
1904  }
1905 
1906  if(joints!=nullptr)
1907  { delete [] joints;
1908  joints = nullptr;}
1909  }
1910 
1911  return ret;
1912 }
1913 
1914 
1921 bool ControlBoardWrapper::setRefSpeeds(const int n_joints, const int *joints, const double *spds)
1922 {
1923  bool ret = true;
1924 
1925  rpcDataMutex.lock();
1926  //Reset subdev_jointsVectorLen vector
1927  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
1928 
1929  // Create a map of joints for each subDevice
1930  int subIndex = 0;
1931  for(int j=0; j<n_joints; j++)
1932  {
1933  subIndex = device.lut[joints[j]].deviceEntry;
1934  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[joints[j]].offset +
1935  rpcData.subdevices_p[subIndex]->base;
1936  rpcData.values[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = spds[j];
1937  rpcData.subdev_jointsVectorLen[subIndex]++;
1938  }
1939 
1940  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
1941  {
1942  if(rpcData.subdevices_p[subIndex]->pos)
1943  {
1944  ret= ret && rpcData.subdevices_p[subIndex]->pos->setRefSpeeds( rpcData.subdev_jointsVectorLen[subIndex],
1945  rpcData.jointNumbers[subIndex],
1946  rpcData.values[subIndex]);
1947  }
1948  else
1949  {
1950  ret=false;
1951  }
1952  }
1953  rpcDataMutex.unlock();
1954  return ret;
1955 }
1956 
1964  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
1965  int subIndex=device.lut[j].deviceEntry;
1966 
1967  SubDevice *p=device.getSubdevice(subIndex);
1968 
1969  if (!p)
1970  return false;
1971 
1972  if (p->pos)
1973  {
1974  return p->pos->setRefAcceleration(off+p->base, acc);
1975  }
1976  return false;
1977 }
1978 
1985 {
1986  bool ret = true;
1987  int j_wrap = 0; // index of the joint from the wrapper side (useful if wrapper joins 2 subdevices)
1988 
1989  // for all subdevices
1990  for(unsigned int subDev_idx=0; subDev_idx < device.subdevices.size(); subDev_idx++)
1991  {
1992  SubDevice *p=device.getSubdevice(subDev_idx);
1993 
1994  if(!p)
1995  return false;
1996 
1997  int wrapped_joints=(p->top - p->base) + 1;
1998  int *joints = new int[wrapped_joints]; // to be defined once and for all?
1999 
2000  if(p->pos)
2001  {
2002  // verione comandi su subset di giunti
2003  for(int j_dev = 0; j_dev < wrapped_joints; j_dev++)
2004  {
2005  joints[j_dev] = p->base + j_dev;
2006  }
2007 
2008  ret = ret && p->pos->setRefAccelerations(wrapped_joints, joints, &accs[j_wrap]);
2009  j_wrap += wrapped_joints;
2010  }
2011  else
2012  {
2013  ret=false;
2014  }
2015 
2016  if(joints!=nullptr)
2017  { delete [] joints;
2018  joints = nullptr;}
2019  }
2020 
2021  return ret;
2022 }
2023 
2030 bool ControlBoardWrapper::setRefAccelerations(const int n_joints, const int *joints, const double *accs)
2031 {
2032  bool ret = true;
2033 
2034  rpcDataMutex.lock();
2035  //Reset subdev_jointsVectorLen vector
2036  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
2037 
2038  // Create a map of joints for each subDevice
2039  int subIndex = 0;
2040  for(int j=0; j<n_joints; j++)
2041  {
2042  subIndex = device.lut[joints[j]].deviceEntry;
2043  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[joints[j]].offset +
2044  rpcData.subdevices_p[subIndex]->base;
2045  rpcData.values[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = accs[j];
2046  rpcData.subdev_jointsVectorLen[subIndex]++;
2047  }
2048 
2049  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
2050  {
2051  if(rpcData.subdevices_p[subIndex]->pos)
2052  {
2053  ret= ret && rpcData.subdevices_p[subIndex]->pos->setRefAccelerations( rpcData.subdev_jointsVectorLen[subIndex],
2054  rpcData.jointNumbers[subIndex],
2055  rpcData.values[subIndex]);
2056  }
2057  else
2058  {
2059  ret=false;
2060  }
2061  }
2062  rpcDataMutex.unlock();
2063  return ret;
2064 }
2065 
2066 
2073 bool ControlBoardWrapper::getRefSpeed(int j, double *ref) {
2074  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
2075  int subIndex=device.lut[j].deviceEntry;
2076 
2077  SubDevice *p=device.getSubdevice(subIndex);
2078 
2079  if (!p)
2080  return false;
2081 
2082  if (p->pos)
2083  {
2084  return p->pos->getRefSpeed(off+p->base, ref);
2085  }
2086  *ref=0;
2087  return false;
2088 }
2089 
2090 
2097 {
2098  auto* references = new double[device.maxNumOfJointsInDevices];
2099  bool ret = true;
2100  for(unsigned int d=0; d<device.subdevices.size(); d++)
2101  {
2102  SubDevice *p=device.getSubdevice(d);
2103  if(!p)
2104  {
2105  ret = false;
2106  break;
2107  }
2108 
2109  if( (p->pos) &&(ret = p->pos->getRefSpeeds(references)))
2110  {
2111  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
2112  {
2113  spds[juser] = references[jdevice];
2114  }
2115  }
2116  else
2117  {
2118  printError("getRefSpeeds", p->id, ret);
2119  ret = false;
2120  break;
2121  }
2122  }
2123 
2124  delete [] references;
2125  return ret;
2126 }
2127 
2128 
2135 bool ControlBoardWrapper::getRefSpeeds(const int n_joints, const int *joints, double *spds)
2136 {
2137  bool ret = true;
2138 
2139  rpcDataMutex.lock();
2140  //Reset subdev_jointsVectorLen vector
2141  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
2142 
2143  // Create a map of joints for each subDevice
2144  int subIndex = 0;
2145  for(int j=0; j<n_joints; j++)
2146  {
2147  subIndex = device.lut[joints[j]].deviceEntry;
2148  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[joints[j]].offset + rpcData.subdevices_p[subIndex]->base;
2149  rpcData.subdev_jointsVectorLen[subIndex]++;
2150  }
2151 
2152  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
2153  {
2154  if(rpcData.subdevices_p[subIndex]->pos)
2155  {
2156  ret= ret && rpcData.subdevices_p[subIndex]->pos->getRefSpeeds( rpcData.subdev_jointsVectorLen[subIndex],
2157  rpcData.jointNumbers[subIndex],
2158  rpcData.values[subIndex]);
2159  }
2160  else
2161  {
2162  ret=false;
2163  }
2164  }
2165 
2166  if(ret)
2167  {
2168  // ReMix values by user expectations
2169  for(int i=0; i<rpcData.deviceNum; i++)
2170  rpcData.subdev_jointsVectorLen[i]=0; // reset tmp index
2171 
2172  // fill the output vector
2173  for(int j=0; j<n_joints; j++)
2174  {
2175  subIndex = device.lut[joints[j]].deviceEntry;
2176  spds[j] = rpcData.values[subIndex][rpcData.subdev_jointsVectorLen[subIndex]];
2177  rpcData.subdev_jointsVectorLen[subIndex]++;
2178  }
2179  }
2180  else
2181  {
2182  for(int j=0; j<n_joints; j++)
2183  {
2184  spds[j] = 0;
2185  }
2186  }
2187  rpcDataMutex.unlock();
2188  return ret;
2189 }
2190 
2198  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
2199  int subIndex=device.lut[j].deviceEntry;
2200 
2201  SubDevice *p=device.getSubdevice(subIndex);
2202 
2203  if (!p)
2204  return false;
2205 
2206  if (p->pos)
2207  {
2208  return p->pos->getRefAcceleration(off+p->base, acc);
2209  }
2210  *acc=0;
2211  return false;
2212 }
2213 
2214 
2221 {
2222  auto* references = new double[device.maxNumOfJointsInDevices];
2223  bool ret = true;
2224  for(unsigned int d=0; d<device.subdevices.size(); d++)
2225  {
2226  SubDevice *p=device.getSubdevice(d);
2227  if(!p)
2228  {
2229  ret = false;
2230  break;
2231  }
2232 
2233  if( (p->pos) &&(ret = p->pos->getRefAccelerations(references)))
2234  {
2235  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
2236  {
2237  accs[juser] = references[jdevice];
2238  }
2239  }
2240  else
2241  {
2242  printError("getRefAccelerations", p->id, ret);
2243  ret = false;
2244  break;
2245  }
2246  }
2247 
2248  delete [] references;
2249  return ret;
2250 }
2251 
2252 
2259 bool ControlBoardWrapper::getRefAccelerations(const int n_joints, const int *joints, double *accs)
2260 {
2261  bool ret = true;
2262 
2263  rpcDataMutex.lock();
2264  //Reset subdev_jointsVectorLen vector
2265  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
2266 
2267  // Create a map of joints for each subDevice
2268  int subIndex = 0;
2269  for(int j=0; j<n_joints; j++)
2270  {
2271  subIndex = device.lut[joints[j]].deviceEntry;
2272  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[joints[j]].offset + rpcData.subdevices_p[subIndex]->base;
2273  rpcData.subdev_jointsVectorLen[subIndex]++;
2274  }
2275 
2276  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
2277  {
2278  if(rpcData.subdevices_p[subIndex]->pos)
2279  {
2280  ret= ret && rpcData.subdevices_p[subIndex]->pos->getRefAccelerations( rpcData.subdev_jointsVectorLen[subIndex],
2281  rpcData.jointNumbers[subIndex],
2282  rpcData.values[subIndex]);
2283  }
2284  else
2285  {
2286  ret=false;
2287  }
2288  }
2289 
2290  if(ret)
2291  {
2292  // ReMix values by user expectations
2293  for(int i=0; i<rpcData.deviceNum; i++)
2294  rpcData.subdev_jointsVectorLen[i]=0; // reset tmp index
2295 
2296  // fill the output vector
2297  for(int j=0; j<n_joints; j++)
2298  {
2299  subIndex = device.lut[joints[j]].deviceEntry;
2300  accs[j] = rpcData.values[subIndex][rpcData.subdev_jointsVectorLen[subIndex]];
2301  rpcData.subdev_jointsVectorLen[subIndex]++;
2302  }
2303  }
2304  else
2305  {
2306  for(int j=0; j<n_joints; j++)
2307  {
2308  accs[j] = 0;
2309  }
2310  }
2311  rpcDataMutex.unlock();
2312  return ret;
2313 }
2314 
2320  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
2321  int subIndex=device.lut[j].deviceEntry;
2322 
2323  SubDevice *p=device.getSubdevice(subIndex);
2324 
2325  if (!p)
2326  return false;
2327 
2328  if (p->pos)
2329  {
2330  return p->pos->stop(off+p->base);
2331  }
2332  return false;
2333 }
2334 
2335 
2341  bool ret=true;
2342 
2343  for(int l=0;l<controlledJoints;l++)
2344  {
2345  int off=device.lut[l].offset;
2346  int subIndex=device.lut[l].deviceEntry;
2347 
2348  SubDevice *p=device.getSubdevice(subIndex);
2349 
2350  if (!p)
2351  return false;
2352 
2353  if (p->pos)
2354  {
2355  ret=ret&&p->pos->stop(off+p->base);
2356  }
2357  else
2358  ret=false;
2359  }
2360  return ret;
2361 }
2362 
2363 
2368 bool ControlBoardWrapper::stop(const int n_joints, const int *joints)
2369 {
2370  bool ret = true;
2371 
2372  rpcDataMutex.lock();
2373  //Reset subdev_jointsVectorLen vector
2374  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
2375 
2376  // Create a map of joints for each subDevice
2377  int subIndex = 0;
2378  for(int j=0; j<n_joints; j++)
2379  {
2380  subIndex = device.lut[joints[j]].deviceEntry;
2381  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[joints[j]].offset + rpcData.subdevices_p[subIndex]->base;
2382  rpcData.subdev_jointsVectorLen[subIndex]++;
2383  }
2384 
2385  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
2386  {
2387  if(rpcData.subdevices_p[subIndex]->pos)
2388  {
2389  ret= ret && rpcData.subdevices_p[subIndex]->pos->stop(rpcData.subdev_jointsVectorLen[subIndex],
2390  rpcData.jointNumbers[subIndex]);
2391  }
2392  else
2393  {
2394  ret=false;
2395  }
2396  }
2397  rpcDataMutex.unlock();
2398  return ret;
2399 }
2400 
2401 
2402 /* IVelocityControl */
2403 
2404 bool ControlBoardWrapper::velocityMove(int j, double v) {
2405  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
2406  int subIndex=device.lut[j].deviceEntry;
2407 
2408  SubDevice *p=device.getSubdevice(subIndex);
2409 
2410  if (!p)
2411  return false;
2412 
2413  if (p->vel)
2414  {
2415  return p->vel->velocityMove(off+p->base, v);
2416  }
2417  return false;
2418 }
2419 
2421 {
2422  bool ret = true;
2423  int j_wrap = 0; // index of the wrapper joint
2424 
2425  for(unsigned int subDev_idx=0; subDev_idx < device.subdevices.size(); subDev_idx++)
2426  {
2427  SubDevice *p=device.getSubdevice(subDev_idx);
2428 
2429  if(!p)
2430  return false;
2431 
2432  int wrapped_joints=(p->top - p->base) + 1;
2433  int *joints = new int[wrapped_joints];
2434 
2435  if(p->vel)
2436  {
2437  // verione comandi su subset di giunti
2438  for(int j_dev = 0; j_dev < wrapped_joints; j_dev++)
2439  {
2440  joints[j_dev] = p->base + j_dev;
2441  }
2442 
2443  ret = ret && p->vel->velocityMove(wrapped_joints, joints, &v[j_wrap]);
2444  j_wrap += wrapped_joints;
2445  }
2446  else
2447  {
2448  ret=false;
2449  }
2450 
2451  if(joints!=nullptr)
2452  { delete [] joints;
2453  joints = nullptr;}
2454  }
2455 
2456  return ret;
2457 }
2458 
2459 /* IEncoders */
2460 
2462  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
2463  int subIndex=device.lut[j].deviceEntry;
2464 
2465  SubDevice *p=device.getSubdevice(subIndex);
2466  if (!p)
2467  return false;
2468 
2469  if (p->iJntEnc)
2470  {
2471  return p->iJntEnc->resetEncoder(off+p->base);
2472  }
2473  return false;
2474 }
2475 
2477  bool ret=true;
2478 
2479  for(int l=0;l<controlledJoints;l++)
2480  {
2481  int off=device.lut[l].offset;
2482  int subIndex=device.lut[l].deviceEntry;
2483 
2484  SubDevice *p=device.getSubdevice(subIndex);
2485  if (!p)
2486  return false;
2487 
2488  if (p->iJntEnc)
2489  {
2490  ret=ret&&p->iJntEnc->resetEncoder(off+p->base);
2491  }
2492  else
2493  ret=false;
2494  }
2495  return ret;
2496 }
2497 
2498 bool ControlBoardWrapper::setEncoder(int j, double val) {
2499  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
2500  int subIndex=device.lut[j].deviceEntry;
2501 
2502  SubDevice *p=device.getSubdevice(subIndex);
2503  if (!p)
2504  return false;
2505 
2506  if (p->iJntEnc)
2507  {
2508  return p->iJntEnc->setEncoder(off+p->base,val);
2509  }
2510  return false;
2511 }
2512 
2513 bool ControlBoardWrapper::setEncoders(const double *vals) {
2514  bool ret=true;
2515 
2516  for(int l=0;l<controlledJoints;l++)
2517  {
2518  int off=device.lut[l].offset;
2519  int subIndex=device.lut[l].deviceEntry;
2520 
2521  SubDevice *p=device.getSubdevice(subIndex);
2522  if (!p)
2523  return false;
2524 
2525  if (p->iJntEnc)
2526  {
2527  ret=ret&&p->iJntEnc->setEncoder(off+p->base, vals[l]);
2528  }
2529  else
2530  ret=false;
2531  }
2532  return ret;
2533 }
2534 
2535 bool ControlBoardWrapper::getEncoder(int j, double *v) {
2536  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
2537  int subIndex=device.lut[j].deviceEntry;
2538 
2539  SubDevice *p=device.getSubdevice(subIndex);
2540  if (!p)
2541  return false;
2542 
2543  if (p->iJntEnc)
2544  {
2545  return p->iJntEnc->getEncoder(off+p->base, v);
2546  }
2547  *v=0.0;
2548  return false;
2549 }
2550 
2552 {
2553  auto* encValues = new double[device.maxNumOfJointsInDevices];
2554  bool ret = true;
2555  for(unsigned int d=0; d<device.subdevices.size(); d++)
2556  {
2557  SubDevice *p=device.getSubdevice(d);
2558  if(!p)
2559  {
2560  ret = false;
2561  break;
2562  }
2563 
2564  if( (p->iJntEnc) &&(ret = p->iJntEnc->getEncoders(encValues)))
2565  {
2566  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
2567  {
2568  encs[juser] = encValues[jdevice];
2569  }
2570  }
2571  else
2572  {
2573  printError("getEncoders", p->id, ret);
2574  ret = false;
2575  break;
2576  }
2577  }
2578 
2579  delete [] encValues;
2580  return ret;
2581 
2582 }
2583 
2584 bool ControlBoardWrapper::getEncodersTimed(double *encs, double *t)
2585 {
2586  auto* encValues = new double[device.maxNumOfJointsInDevices];
2587  auto* tValues = new double[device.maxNumOfJointsInDevices];
2588  bool ret = true;
2589  for(unsigned int d=0; d<device.subdevices.size(); d++)
2590  {
2591  SubDevice *p=device.getSubdevice(d);
2592  if(!p)
2593  {
2594  ret = false;
2595  break;
2596  }
2597 
2598  if( (p->iJntEnc) &&(ret = p->iJntEnc->getEncodersTimed(encValues, tValues)))
2599  {
2600  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
2601  {
2602  encs[juser] = encValues[jdevice];
2603  t[juser] = tValues[jdevice];
2604  }
2605  }
2606  else
2607  {
2608  printError("getEncodersTimed", p->id, ret);
2609  ret = false;
2610  break;
2611  }
2612  }
2613 
2614  delete [] encValues;
2615  delete [] tValues;
2616  return ret;
2617 }
2618 
2619 bool ControlBoardWrapper::getEncoderTimed(int j, double *v, double *t) {
2620  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
2621  int subIndex=device.lut[j].deviceEntry;
2622 
2623  SubDevice *p=device.getSubdevice(subIndex);
2624  if (!p)
2625  return false;
2626 
2627  if (p->iJntEnc)
2628  {
2629  return p->iJntEnc->getEncoderTimed(off+p->base, v, t);
2630  }
2631  *v=0.0;
2632  return false;
2633 }
2634 
2635 bool ControlBoardWrapper::getEncoderSpeed(int j, double *sp) {
2636  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
2637  int subIndex=device.lut[j].deviceEntry;
2638 
2639  SubDevice *p=device.getSubdevice(subIndex);
2640  if (!p)
2641  return false;
2642 
2643  if (p->iJntEnc)
2644  {
2645  return p->iJntEnc->getEncoderSpeed(off+p->base, sp);
2646  }
2647  *sp=0.0;
2648  return false;
2649 }
2650 
2652 {
2653  auto* sValues = new double[device.maxNumOfJointsInDevices];
2654  bool ret = true;
2655  for(unsigned int d=0; d<device.subdevices.size(); d++)
2656  {
2657  SubDevice *p=device.getSubdevice(d);
2658  if(!p)
2659  {
2660  ret = false;
2661  break;
2662  }
2663 
2664  if( (p->iJntEnc) &&(ret = p->iJntEnc->getEncoderSpeeds(sValues)))
2665  {
2666  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
2667  {
2668  spds[juser] = sValues[jdevice];
2669  }
2670  }
2671  else
2672  {
2673  printError("getEncoderSpeeds", p->id, ret);
2674  ret = false;
2675  break;
2676  }
2677  }
2678 
2679  delete [] sValues;
2680  return ret;
2681 }
2682 
2684  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
2685  int subIndex=device.lut[j].deviceEntry;
2686 
2687  SubDevice *p=device.getSubdevice(subIndex);
2688  if (!p)
2689  return false;
2690 
2691  if (p->iJntEnc)
2692  {
2693  return p->iJntEnc->getEncoderAcceleration(off+p->base,acc);
2694  }
2695  *acc=0.0;
2696  return false;
2697 }
2698 
2700 {
2701  auto* aValues = new double[device.maxNumOfJointsInDevices];
2702  bool ret = true;
2703  for(unsigned int d=0; d<device.subdevices.size(); d++)
2704  {
2705  SubDevice *p=device.getSubdevice(d);
2706  if(!p)
2707  {
2708  ret = false;
2709  break;
2710  }
2711 
2712  if( (p->iJntEnc) &&(ret = p->iJntEnc->getEncoderAccelerations(aValues)))
2713  {
2714  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
2715  {
2716  accs[juser] = aValues[jdevice];
2717  }
2718  }
2719  else
2720  {
2721  printError("getEncoderAccelerations", p->id, ret);
2722  ret = false;
2723  break;
2724  }
2725  }
2726 
2727  delete [] aValues;
2728  return ret;
2729 }
2730 
2731 /* IMotor */
2733  *num=controlledJoints;
2734  return true;
2735 }
2736 
2737 bool ControlBoardWrapper::getTemperature (int m, double* val) {
2738  int off=device.lut[m].offset;
2739  int subIndex=device.lut[m].deviceEntry;
2740 
2741  SubDevice *p=device.getSubdevice(subIndex);
2742  if (!p)
2743  return false;
2744 
2745  if (p->imotor)
2746  {
2747  return p->imotor->getTemperature(off+p->base, val);
2748  }
2749  *val=0.0;
2750  return false;
2751 }
2752 
2754 {
2755  auto* temps = new double[device.maxNumOfJointsInDevices];
2756  bool ret = true;
2757  for(unsigned int d=0; d<device.subdevices.size(); d++)
2758  {
2759  SubDevice *p=device.getSubdevice(d);
2760  if(!p)
2761  {
2762  ret = false;
2763  break;
2764  }
2765 
2766  if( (p->imotor) &&(ret = p->imotor->getTemperatures(temps)))
2767  {
2768  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
2769  {
2770  vals[juser] = temps[jdevice];
2771  }
2772  }
2773  else
2774  {
2775  printError("getTemperatures", p->id, ret);
2776  ret = false;
2777  break;
2778  }
2779  }
2780 
2781  delete [] temps;
2782  return ret;
2783 }
2784 
2785 bool ControlBoardWrapper::getTemperatureLimit (int m, double* val) {
2786  int off=device.lut[m].offset;
2787  int subIndex=device.lut[m].deviceEntry;
2788 
2789  SubDevice *p=device.getSubdevice(subIndex);
2790  if (!p)
2791  return false;
2792 
2793  if (p->imotor)
2794  {
2795  return p->imotor->getTemperatureLimit(off+p->base, val);
2796  }
2797  *val=0.0;
2798  return false;
2799 }
2800 
2801 bool ControlBoardWrapper::setTemperatureLimit (int m, const double val) {
2802  int off=device.lut[m].offset;
2803  int subIndex=device.lut[m].deviceEntry;
2804 
2805  SubDevice *p=device.getSubdevice(subIndex);
2806  if (!p)
2807  return false;
2808 
2809  if (p->imotor)
2810  {
2811  return p->imotor->setTemperatureLimit(off+p->base,val);
2812  }
2813  return false;
2814 }
2815 
2816 bool ControlBoardWrapper::getGearboxRatio(int m, double* val) {
2817  int off = device.lut[m].offset;
2818  int subIndex = device.lut[m].deviceEntry;
2819 
2820  SubDevice *p = device.getSubdevice(subIndex);
2821  if (!p)
2822  return false;
2823 
2824  if (p->imotor)
2825  {
2826  return p->imotor->getGearboxRatio(off + p->base, val);
2827  }
2828  *val = 0.0;
2829  return false;
2830 }
2831 
2832 bool ControlBoardWrapper::setGearboxRatio(int m, const double val) {
2833  int off = device.lut[m].offset;
2834  int subIndex = device.lut[m].deviceEntry;
2835 
2836  SubDevice *p = device.getSubdevice(subIndex);
2837  if (!p)
2838  return false;
2839 
2840  if (p->imotor)
2841  {
2842  return p->imotor->setGearboxRatio(off + p->base, val);
2843  }
2844  return false;
2845 }
2846 
2847 /* IRemoteVariables */
2849  bool b = true;
2850 
2851  for (unsigned int i = 0; i < device.subdevices.size(); i++)
2852  {
2853  SubDevice *p = device.getSubdevice(i);
2854 
2855  if (!p) return false;
2856  if (!p->iVar) return false;
2857  yarp::os::Bottle tmpval;
2858  b &= p->iVar->getRemoteVariable(key, tmpval);
2859  if (b) val.append(tmpval);
2860  }
2861 
2862  return b;
2863 }
2864 
2866 {
2867  size_t bottle_size = val.size();
2868  size_t device_size = device.subdevices.size();
2869  if (bottle_size != device_size)
2870  {
2871  yCError(CONTROLBOARDWRAPPER, "setRemoteVariable bottle_size != device_size failure");
2872  return false;
2873  }
2874 
2875  bool b = true;
2876  for (unsigned int i = 0; i < device_size; i++)
2877  {
2878  SubDevice *p = device.getSubdevice(i);
2879  if (!p) { yCError(CONTROLBOARDWRAPPER, "setRemoteVariable !p failure"); return false; }
2880  if (!p->iVar) { yCError(CONTROLBOARDWRAPPER, "setRemoteVariable !p->iVar failure"); return false; }
2881  Bottle* partial_val = val.get(i).asList();
2882  if (partial_val)
2883  {
2884  b &= p->iVar->setRemoteVariable(key, *partial_val);
2885  }
2886  else
2887  {
2888  yCError(CONTROLBOARDWRAPPER, "setRemoteVariable general failure");
2889  return false;
2890  }
2891  }
2892 
2893  return b;
2894 }
2895 
2897 {
2898  //int off = device.lut[0].offset;
2899  int subIndex = device.lut[0].deviceEntry;
2900  SubDevice *p = device.getSubdevice(subIndex);
2901 
2902  if (!p)
2903  return false;
2904 
2905  if (p->iVar)
2906  {
2907  return p->iVar->getRemoteVariablesList(listOfKeys);
2908  }
2909  return false;
2910 }
2911 
2912 /* IMotorEncoders */
2913 
2915  int off=device.lut[m].offset;
2916  int subIndex=device.lut[m].deviceEntry;
2917 
2918  SubDevice *p=device.getSubdevice(subIndex);
2919  if (!p)
2920  return false;
2921 
2922  if (p->iMotEnc)
2923  {
2924  return p->iMotEnc->resetMotorEncoder(off+p->base);
2925  }
2926  return false;
2927 }
2928 
2930  bool ret=true;
2931 
2932  for(int l=0;l<controlledJoints;l++)
2933  {
2934  int off=device.lut[l].offset;
2935  int subIndex=device.lut[l].deviceEntry;
2936 
2937  SubDevice *p=device.getSubdevice(subIndex);
2938  if (!p)
2939  return false;
2940 
2941  if (p->iMotEnc)
2942  {
2943  ret=ret&&p->iMotEnc->resetMotorEncoder(off+p->base);
2944  }
2945  else
2946  ret=false;
2947  }
2948  return ret;
2949 }
2950 
2951 bool ControlBoardWrapper::setMotorEncoder(int m, const double val) {
2952  int off=device.lut[m].offset;
2953  int subIndex=device.lut[m].deviceEntry;
2954 
2955  SubDevice *p=device.getSubdevice(subIndex);
2956  if (!p)
2957  return false;
2958 
2959  if (p->iMotEnc)
2960  {
2961  return p->iMotEnc->setMotorEncoder(off+p->base,val);
2962  }
2963  return false;
2964 }
2965 
2966 bool ControlBoardWrapper::setMotorEncoders(const double *vals) {
2967  bool ret=true;
2968 
2969  for(int l=0;l<controlledJoints;l++)
2970  {
2971  int off=device.lut[l].offset;
2972  int subIndex=device.lut[l].deviceEntry;
2973 
2974  SubDevice *p=device.getSubdevice(subIndex);
2975  if (!p)
2976  return false;
2977 
2978  if (p->iMotEnc)
2979  {
2980  ret=ret&&p->iMotEnc->setMotorEncoder(off+p->base, vals[l]);
2981  }
2982  else
2983  ret=false;
2984  }
2985  return ret;
2986 }
2987 
2989  int off=device.lut[m].offset;
2990  int subIndex=device.lut[m].deviceEntry;
2991 
2992  SubDevice *p=device.getSubdevice(subIndex);
2993  if (!p)
2994  return false;
2995 
2996  if (p->iMotEnc)
2997  {
2998  return p->iMotEnc->setMotorEncoderCountsPerRevolution(off+p->base,cpr);
2999  }
3000  return false;
3001 }
3002 
3004  int off=device.lut[m].offset;
3005  int subIndex=device.lut[m].deviceEntry;
3006 
3007  SubDevice *p=device.getSubdevice(subIndex);
3008  if (!p)
3009  return false;
3010 
3011  if (p->iMotEnc)
3012  {
3013  return p->iMotEnc->getMotorEncoderCountsPerRevolution(off+p->base, cpr);
3014  }
3015  *cpr=0.0;
3016  return false;
3017 }
3018 
3020  int off=device.lut[m].offset;
3021  int subIndex=device.lut[m].deviceEntry;
3022 
3023  SubDevice *p=device.getSubdevice(subIndex);
3024  if (!p)
3025  return false;
3026 
3027  if (p->iMotEnc)
3028  {
3029  return p->iMotEnc->getMotorEncoder(off+p->base, v);
3030  }
3031  *v=0.0;
3032  return false;
3033 }
3034 
3036 {
3037 
3038  auto* encValues = new double[device.maxNumOfJointsInDevices];
3039  bool ret = true;
3040  for(unsigned int d=0; d<device.subdevices.size(); d++)
3041  {
3042  SubDevice *p=device.getSubdevice(d);
3043  if(!p)
3044  {
3045  ret = false;
3046  break;
3047  }
3048 
3049  if( (p->iMotEnc) &&(ret = p->iMotEnc->getMotorEncoders(encValues)))
3050  {
3051  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
3052  {
3053  encs[juser] = encValues[jdevice];
3054  }
3055  }
3056  else
3057  {
3058  printError("getMotorEncoders", p->id, ret);
3059  ret = false;
3060  break;
3061  }
3062  }
3063 
3064  delete [] encValues;
3065  return ret;
3066 }
3067 
3069 {
3070  auto* encValues = new double[device.maxNumOfJointsInDevices];
3071  auto* tValues = new double[device.maxNumOfJointsInDevices];
3072  bool ret = true;
3073  for(unsigned int d=0; d<device.subdevices.size(); d++)
3074  {
3075  SubDevice *p=device.getSubdevice(d);
3076  if(!p)
3077  {
3078  ret = false;
3079  break;
3080  }
3081 
3082  if( (p->iMotEnc) &&(ret = p->iMotEnc->getMotorEncodersTimed(encValues, tValues)))
3083  {
3084  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
3085  {
3086  encs[juser] = encValues[jdevice];
3087  t[juser] = tValues[jdevice];
3088  }
3089  }
3090  else
3091  {
3092  printError("getMotorEncodersTimed", p->id, ret);
3093  ret = false;
3094  break;
3095  }
3096  }
3097 
3098  delete [] encValues;
3099  delete [] tValues;
3100  return ret;
3101 }
3102 
3103 bool ControlBoardWrapper::getMotorEncoderTimed(int m, double *v, double *t) {
3104  int off=device.lut[m].offset;
3105  int subIndex=device.lut[m].deviceEntry;
3106 
3107  SubDevice *p=device.getSubdevice(subIndex);
3108  if (!p)
3109  return false;
3110 
3111  if (p->iMotEnc)
3112  {
3113  return p->iMotEnc->getMotorEncoderTimed(off+p->base, v, t);
3114  }
3115  *v=0.0;
3116  return false;
3117 }
3118 
3120  int off=device.lut[m].offset;
3121  int subIndex=device.lut[m].deviceEntry;
3122 
3123  SubDevice *p=device.getSubdevice(subIndex);
3124  if (!p)
3125  return false;
3126 
3127  if (p->iMotEnc)
3128  {
3129  return p->iMotEnc->getMotorEncoderSpeed(off+p->base, sp);
3130  }
3131  *sp=0.0;
3132  return false;
3133 }
3134 
3136 {
3137  auto* sValues = new double[device.maxNumOfJointsInDevices];
3138  bool ret = true;
3139  for(unsigned int d=0; d<device.subdevices.size(); d++)
3140  {
3141  SubDevice *p=device.getSubdevice(d);
3142  if(!p)
3143  {
3144  ret = false;
3145  break;
3146  }
3147 
3148  if( (p->iMotEnc) &&(ret = p->iMotEnc->getMotorEncoderSpeeds(sValues)))
3149  {
3150  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
3151  {
3152  spds[juser] = sValues[jdevice];
3153  }
3154  }
3155  else
3156  {
3157  printError("getMotorEncoderSpeeds", p->id, ret);
3158  ret = false;
3159  break;
3160  }
3161  }
3162 
3163  delete [] sValues;
3164  return ret;
3165 }
3166 
3168  int off=device.lut[m].offset;
3169  int subIndex=device.lut[m].deviceEntry;
3170 
3171  SubDevice *p=device.getSubdevice(subIndex);
3172  if (!p)
3173  return false;
3174 
3175  if (p->iMotEnc)
3176  {
3177  return p->iMotEnc->getMotorEncoderAcceleration(off+p->base,acc);
3178  }
3179  *acc=0.0;
3180  return false;
3181 }
3182 
3184 {
3185  auto* aValues = new double[device.maxNumOfJointsInDevices];
3186  bool ret = true;
3187  for(unsigned int d=0; d<device.subdevices.size(); d++)
3188  {
3189  SubDevice *p=device.getSubdevice(d);
3190  if(!p)
3191  {
3192  ret = false;
3193  break;
3194  }
3195 
3196  if( (p->iMotEnc) &&(ret = p->iMotEnc->getMotorEncoderAccelerations(aValues)))
3197  {
3198  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
3199  {
3200  accs[juser] = aValues[jdevice];
3201  }
3202  }
3203  else
3204  {
3205  printError("getMotorEncoderAccelerations", p->id, ret);
3206  ret = false;
3207  break;
3208  }
3209  }
3210 
3211  delete [] aValues;
3212  return ret;
3213 
3214 }
3215 
3216 
3218  *num=controlledJoints;
3219  return true;
3220 }
3221 
3222 /* IAmplifierControl */
3223 
3225 {
3226  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3227  int subIndex=device.lut[j].deviceEntry;
3228 
3229  SubDevice *p=device.getSubdevice(subIndex);
3230  if (!p)
3231  return false;
3232 
3233  if (p->amp)
3234  {
3235  return p->amp->enableAmp(off+p->base);
3236  }
3237  return false;
3238 }
3239 
3241 {
3242  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3243  int subIndex=device.lut[j].deviceEntry;
3244 
3245  bool ret = true;
3246  SubDevice *p=device.getSubdevice(subIndex);
3247  if (!p)
3248  return false;
3249 
3250  // Use the newer interface if available, otherwise fallback on the old one.
3251  if(p->iMode)
3252  {
3253  ret = p->iMode->setControlMode(off+p->base, VOCAB_CM_IDLE);
3254  }
3255  else
3256  {
3257  if (p->pos)
3258  ret = p->amp->disableAmp(off+p->base);
3259  else
3260  ret = false;
3261  }
3262  return ret;
3263 }
3264 
3266 {
3267  int *status = new int[device.maxNumOfJointsInDevices];
3268  bool ret = true;
3269  for(unsigned int d=0; d<device.subdevices.size(); d++)
3270  {
3271  SubDevice *p=device.getSubdevice(d);
3272  if(!p)
3273  {
3274  ret = false;
3275  break;
3276  }
3277 
3278  if( (p->amp) &&(ret = p->amp->getAmpStatus(status)))
3279  {
3280  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
3281  {
3282  st[juser] = status[jdevice];
3283  }
3284  }
3285  else
3286  {
3287  printError("getAmpStatus", p->id, ret);
3288  ret = false;
3289  break;
3290  }
3291  }
3292 
3293  delete [] status;
3294  return ret;
3295 }
3296 
3298 {
3299  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3300  int subIndex=device.lut[j].deviceEntry;
3301 
3302  SubDevice *p=device.getSubdevice(subIndex);
3303  if (p && p->amp)
3304  {
3305  return p->amp->getAmpStatus(off+p->base,v);
3306  }
3307  *v=0;
3308  return false;
3309 }
3310 
3312 {
3313  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3314  int subIndex=device.lut[j].deviceEntry;
3315 
3316  SubDevice *p=device.getSubdevice(subIndex);
3317  if (!p)
3318  return false;
3319 
3320  if (p->amp)
3321  {
3322  return p->amp->setMaxCurrent(off+p->base,v);
3323  }
3324  return false;
3325 }
3326 
3328 {
3329  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3330  int subIndex=device.lut[j].deviceEntry;
3331 
3332  SubDevice *p=device.getSubdevice(subIndex);
3333  if (!p)
3334  {
3335  *v=0.0;
3336  return false;
3337  }
3338 
3339  if (p->amp)
3340  {
3341  return p->amp->getMaxCurrent(off+p->base,v);
3342  }
3343  *v=0.0;
3344  return false;
3345 }
3346 
3348 {
3349  int off=device.lut[m].offset;
3350  int subIndex=device.lut[m].deviceEntry;
3351 
3352  SubDevice *p=device.getSubdevice(subIndex);
3353  if(!p)
3354  {
3355  *val=0.0;
3356  return false;
3357  }
3358 
3359  if(!p->amp)
3360  {
3361  *val=0.0;
3362  return false;
3363  }
3364  return p->amp->getNominalCurrent(off+p->base, val);
3365 }
3366 
3367 bool ControlBoardWrapper::getPeakCurrent(int m, double *val)
3368 {
3369  int off=device.lut[m].offset;
3370  int subIndex=device.lut[m].deviceEntry;
3371 
3372  SubDevice *p=device.getSubdevice(subIndex);
3373  if(!p)
3374  {
3375  *val=0.0;
3376  return false;
3377  }
3378 
3379  if(!p->amp)
3380  {
3381  *val=0.0;
3382  return false;
3383  }
3384  return p->amp->getPeakCurrent(off+p->base, val);
3385 }
3386 
3387 bool ControlBoardWrapper::setPeakCurrent(int m, const double val)
3388 {
3389  int off=device.lut[m].offset;
3390  int subIndex=device.lut[m].deviceEntry;
3391 
3392  SubDevice *p=device.getSubdevice(subIndex);
3393  if (!p)
3394  return false;
3395 
3396  if (!p->amp)
3397  {
3398  return false;
3399  }
3400  return p->amp->setPeakCurrent(off+p->base, val);
3401 }
3402 
3403 bool ControlBoardWrapper::setNominalCurrent(int m, const double val)
3404 {
3405  int off = device.lut[m].offset;
3406  int subIndex = device.lut[m].deviceEntry;
3407 
3408  SubDevice *p = device.getSubdevice(subIndex);
3409  if (!p)
3410  return false;
3411 
3412  if (!p->amp)
3413  {
3414  return false;
3415  }
3416  return p->amp->setNominalCurrent(off + p->base, val);
3417 }
3418 
3419 bool ControlBoardWrapper::getPWM(int m, double* val)
3420 {
3421  int off=device.lut[m].offset;
3422  int subIndex=device.lut[m].deviceEntry;
3423  SubDevice *p=device.getSubdevice(subIndex);
3424 
3425  yCTrace(CONTROLBOARDWRAPPER) << "CBW2::getPWMlimit j" << off+p->base << " p " << (p?"1":"0") << " amp " << (p->amp?"1":"0");
3426  if(!p)
3427  {
3428  *val=0.0;
3429  return false;
3430  }
3431 
3432  if(!p->amp)
3433  {
3434  *val=0.0;
3435  return false;
3436  }
3437  return p->amp->getPWM(off+p->base, val);
3438 }
3439 bool ControlBoardWrapper::getPWMLimit(int m, double* val)
3440 {
3441  int off=device.lut[m].offset;
3442  int subIndex=device.lut[m].deviceEntry;
3443 
3444  SubDevice *p=device.getSubdevice(subIndex);
3445  yCTrace(CONTROLBOARDWRAPPER) << "CBW2::getPWMlimit j" << off+p->base << " p " << (p?"1":"0") << " amp " << (p->amp?"1":"0");
3446 
3447  if(!p)
3448  {
3449  *val=0.0;
3450  return false;
3451  }
3452 
3453  if(!p->amp)
3454  {
3455  *val=0.0;
3456  return false;
3457  }
3458  return p->amp->getPWMLimit(off+p->base, val);
3459 }
3460 bool ControlBoardWrapper::setPWMLimit(int m, const double val)
3461 {
3462  int off=device.lut[m].offset;
3463  int subIndex=device.lut[m].deviceEntry;
3464 
3465  SubDevice *p=device.getSubdevice(subIndex);
3466  if (!p)
3467  return false;
3468 
3469  if (!p->amp)
3470  {
3471  return false;
3472  }
3473  return p->amp->setPWMLimit(off+p->base, val);
3474 }
3475 
3477 {
3478  int off=device.lut[m].offset;
3479  int subIndex=device.lut[m].deviceEntry;
3480 
3481  SubDevice *p=device.getSubdevice(subIndex);
3482  if(!p)
3483  {
3484  *val=0.0;
3485  return false;
3486  }
3487 
3488  if(!p->amp)
3489  {
3490  *val=0.0;
3491  return false;
3492  }
3493  return p->amp->getPowerSupplyVoltage(off+p->base, val);
3494 }
3495 
3496 
3497 /* IControlLimits */
3498 
3499 bool ControlBoardWrapper::setLimits(int j, double min, double max)
3500 {
3501  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3502  int subIndex=device.lut[j].deviceEntry;
3503 
3504  SubDevice *p=device.getSubdevice(subIndex);
3505  if (!p)
3506  return false;
3507 
3508  if (p->lim)
3509  {
3510  return p->lim->setLimits(off+p->base,min, max);
3511  }
3512  return false;
3513 }
3514 
3515 bool ControlBoardWrapper::getLimits(int j, double *min, double *max)
3516 {
3517  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3518  int subIndex=device.lut[j].deviceEntry;
3519 
3520  SubDevice *p=device.getSubdevice(subIndex);
3521  if (!p)
3522  {
3523  *min=0.0;
3524  *max=0.0;
3525  return false;
3526  }
3527 
3528  if (p->lim)
3529  {
3530  return p->lim->getLimits(off+p->base,min, max);
3531  }
3532  *min=0.0;
3533  *max=0.0;
3534  return false;
3535 }
3536 
3537 bool ControlBoardWrapper::setVelLimits(int j, double min, double max)
3538 {
3539  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3540  int subIndex=device.lut[j].deviceEntry;
3541 
3542  SubDevice *p=device.getSubdevice(subIndex);
3543  if (!p)
3544  return false;
3545 
3546  if (!p->lim)
3547  {
3548  return false;
3549  }
3550  return p->lim->setVelLimits(off+p->base,min, max);
3551 }
3552 
3553 bool ControlBoardWrapper::getVelLimits(int j, double *min, double *max)
3554 {
3555  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3556  int subIndex=device.lut[j].deviceEntry;
3557 
3558  *min=0.0;
3559  *max=0.0;
3560 
3561  SubDevice *p=device.getSubdevice(subIndex);
3562  if (!p)
3563  {
3564  return false;
3565  }
3566 
3567  if(!p->lim)
3568  {
3569  return false;
3570  }
3571  return p->lim->getVelLimits(off+p->base,min, max);
3572 }
3573 
3574 /* IRemoteCalibrator */
3576 {
3579 }
3580 
3582 {
3585 }
3586 
3588 {
3590  if(!getCalibratorDevice())
3591  return false;
3592  return IRemoteCalibrator::getCalibratorDevice()->calibrateSingleJoint(j);
3593 }
3594 
3596 {
3598  if(!getCalibratorDevice())
3599  return false;
3600 
3602 }
3603 
3605 {
3607  if(!getCalibratorDevice())
3608  return false;
3609 
3611 }
3612 
3614 {
3616  if(!getCalibratorDevice())
3617  return false;
3618 
3620 }
3621 
3623 {
3625  if(!getCalibratorDevice())
3626  return false;
3627 
3628  return getCalibratorDevice()->parkSingleJoint(j, _wait);
3629 }
3630 
3632 {
3634  if(!getCalibratorDevice())
3635  return false;
3636 
3637  return getCalibratorDevice()->parkWholePart();
3638 }
3639 
3641 {
3643  if(!getCalibratorDevice())
3644  return false;
3645 
3646  return getCalibratorDevice()->quitCalibrate();
3647 }
3648 
3650 {
3652  if(!getCalibratorDevice())
3653  return false;
3654 
3655  return getCalibratorDevice()->quitPark();
3656 }
3657 
3658 
3659 /* IControlCalibration */
3660 bool ControlBoardWrapper::calibrateAxisWithParams(int j, unsigned int ui, double v1, double v2, double v3)
3661 {
3662  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3663  int subIndex=device.lut[j].deviceEntry;
3664 
3665  SubDevice *p = device.getSubdevice(subIndex);
3666  if (p && p->calib)
3667  {
3668  return p->calib->calibrateAxisWithParams(off+p->base, ui,v1,v2,v3);
3669  }
3670  return false;
3671 }
3672 
3674 {
3675  int off = device.lut[j].offset;
3676  int subIndex = device.lut[j].deviceEntry;
3677 
3678  SubDevice *p = device.getSubdevice(subIndex);
3679  if (p && p->calib)
3680  {
3681  return p->calib->setCalibrationParameters(off + p->base, params);
3682  }
3683  return false;
3684 }
3685 
3687 {
3688  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3689  int subIndex=device.lut[j].deviceEntry;
3690 
3691  SubDevice *p=device.getSubdevice(subIndex);
3692  if (!p)
3693  return false;
3694 
3695  if (p->calib)
3696  {
3697  return p->calib->calibrationDone(off+p->base);
3698  }
3699  return false;
3700 }
3701 
3703 {
3704  yCError(CONTROLBOARDWRAPPER, "Calling abortPark -- not implemented");
3705  return false;
3706 }
3707 
3709 {
3710  yCError(CONTROLBOARDWRAPPER, "Calling abortCalibration -- not implemented");
3711  return false;
3712 }
3713 
3714 /* IAxisInfo */
3715 
3716 bool ControlBoardWrapper::getAxisName(int j, std::string& name)
3717 {
3718  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3719  int subIndex=device.lut[j].deviceEntry;
3720 
3721  SubDevice *p=device.getSubdevice(subIndex);
3722  if (!p)
3723  return false;
3724 
3725  if (p->info)
3726  {
3727  return p->info->getAxisName(off+p->base, name);
3728  }
3729  return false;
3730 }
3731 
3733 {
3734  int off = device.lut[j].offset;
3735  int subIndex = device.lut[j].deviceEntry;
3736 
3737  SubDevice *p = device.getSubdevice(subIndex);
3738  if (!p)
3739  return false;
3740 
3741  if (p->info)
3742  {
3743  return p->info->getJointType(off + p->base, type);
3744  }
3745  return false;
3746 }
3747 
3749 {
3750  auto* references = new double[device.maxNumOfJointsInDevices];
3751  bool ret = true;
3752  for(unsigned int d=0; d<device.subdevices.size(); d++)
3753  {
3754  SubDevice *p=device.getSubdevice(d);
3755  if(!p)
3756  {
3757  ret = false;
3758  break;
3759  }
3760 
3761  if( (p->iTorque) &&(ret = p->iTorque->getRefTorques(references)))
3762  {
3763  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
3764  {
3765  refs[juser] = references[jdevice];
3766  }
3767  }
3768  else
3769  {
3770  printError("getRefTorques", p->id, ret);
3771  ret = false;
3772  break;
3773  }
3774  }
3775 
3776  delete [] references;
3777  return ret;
3778 }
3779 
3781 {
3782 
3783  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3784  int subIndex=device.lut[j].deviceEntry;
3785 
3786  SubDevice *p=device.getSubdevice(subIndex);
3787  if (!p)
3788  return false;
3789 
3790  if (p->iTorque)
3791  {
3792  return p->iTorque->getRefTorque(off+p->base, t);
3793  }
3794  return false;
3795 }
3796 
3798 {
3799  bool ret=true;
3800 
3801  for(int l=0;l<controlledJoints;l++)
3802  {
3803  int off=device.lut[l].offset;
3804  int subIndex=device.lut[l].deviceEntry;
3805 
3806  SubDevice *p=device.getSubdevice(subIndex);
3807  if (!p)
3808  return false;
3809 
3810  if (p->iTorque)
3811  {
3812  ret=ret&&p->iTorque->setRefTorque(off+p->base, t[l]);
3813  }
3814  else
3815  ret=false;
3816  }
3817  return ret;
3818 }
3819 
3821 {
3822  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3823  int subIndex=device.lut[j].deviceEntry;
3824 
3825  SubDevice *p=device.getSubdevice(subIndex);
3826  if (!p)
3827  return false;
3828 
3829  if (p->iTorque)
3830  {
3831  return p->iTorque->setRefTorque(off+p->base, t);
3832  }
3833  return false;
3834 }
3835 
3836 bool ControlBoardWrapper::setRefTorques(const int n_joints, const int *joints, const double *t)
3837 {
3838  bool ret = true;
3839 
3840  rpcDataMutex.lock();
3841  //Reset subdev_jointsVectorLen vector
3842  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
3843 
3844  // Create a map of joints for each subDevice
3845  int subIndex = 0;
3846  for(int j=0; j<n_joints; j++)
3847  {
3848  subIndex = device.lut[joints[j]].deviceEntry;
3849  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[joints[j]].offset + rpcData.subdevices_p[subIndex]->base;
3850  rpcData.values[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = t[j];
3851  rpcData.subdev_jointsVectorLen[subIndex]++;
3852  }
3853 
3854  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
3855  {
3856  if(rpcData.subdevices_p[subIndex]->iTorque)
3857  {
3858  ret= ret && rpcData.subdevices_p[subIndex]->iTorque->setRefTorques(rpcData.subdev_jointsVectorLen[subIndex],
3859  rpcData.jointNumbers[subIndex],
3860  rpcData.values[subIndex]);
3861  }
3862  else
3863  {
3864  ret=false;
3865  }
3866  }
3867  rpcDataMutex.unlock();
3868  return ret;
3869 }
3870 
3872 {
3873  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3874  int subIndex=device.lut[j].deviceEntry;
3875 
3876  SubDevice *p=device.getSubdevice(subIndex);
3877  if (!p)
3878  return false;
3879 
3880  if (p->iTorque)
3881  {
3882  return p->iTorque->getMotorTorqueParams(off+p->base, params);
3883  }
3884  return false;
3885 }
3886 
3888 {
3889  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3890  int subIndex=device.lut[j].deviceEntry;
3891 
3892  SubDevice *p=device.getSubdevice(subIndex);
3893  if (!p)
3894  return false;
3895 
3896  if (p->iTorque)
3897  {
3898  return p->iTorque->setMotorTorqueParams(off+p->base, params);
3899  }
3900  return false;
3901 }
3902 
3903 bool ControlBoardWrapper::setImpedance(int j, double stiff, double damp)
3904 {
3905  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3906  int subIndex=device.lut[j].deviceEntry;
3907 
3908  SubDevice *p=device.getSubdevice(subIndex);
3909  if (!p)
3910  return false;
3911 
3912  if (p->iImpedance)
3913  {
3914  return p->iImpedance->setImpedance(off+p->base, stiff, damp);
3915  }
3916 
3917  return false;
3918 }
3919 
3921 {
3922  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3923  int subIndex=device.lut[j].deviceEntry;
3924 
3925  SubDevice *p=device.getSubdevice(subIndex);
3926  if (!p)
3927  return false;
3928 
3929  if (p->iImpedance)
3930  {
3931  return p->iImpedance->setImpedanceOffset(off+p->base, offset);
3932  }
3933 
3934  return false;
3935 }
3936 
3937 bool ControlBoardWrapper::getTorque(int j, double *t)
3938 {
3939  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3940  int subIndex=device.lut[j].deviceEntry;
3941 
3942  SubDevice *p=device.getSubdevice(subIndex);
3943  if (!p)
3944  return false;
3945 
3946  if (p->iTorque)
3947  {
3948  return p->iTorque->getTorque(off+p->base, t);
3949  }
3950 
3951  return false;
3952 }
3953 
3955 {
3956  auto* trqs = new double[device.maxNumOfJointsInDevices];
3957  bool ret = true;
3958  for(unsigned int d=0; d<device.subdevices.size(); d++)
3959  {
3960  SubDevice *p=device.getSubdevice(d);
3961  if(!p)
3962  {
3963  ret = false;
3964  break;
3965  }
3966 
3967  if( (p->iTorque) &&(ret = p->iTorque->getTorques(trqs)))
3968  {
3969  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
3970  {
3971  t[juser] = trqs[jdevice];
3972  }
3973  }
3974  else
3975  {
3976  printError("getTorques", p->id, ret);
3977  ret = false;
3978  break;
3979  }
3980  }
3981 
3982  delete [] trqs;
3983  return ret;
3984 
3985  }
3986 
3987 bool ControlBoardWrapper::getTorqueRange(int j, double *min, double *max)
3988 {
3989  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
3990  int subIndex=device.lut[j].deviceEntry;
3991 
3992  SubDevice *p=device.getSubdevice(subIndex);
3993  if (!p)
3994  return false;
3995 
3996  if (p->iTorque)
3997  {
3998  return p->iTorque->getTorqueRange(off+p->base, min, max);
3999  }
4000 
4001  return false;
4002 }
4003 
4004 bool ControlBoardWrapper::getTorqueRanges(double *min, double *max)
4005 {
4006  auto* t_min = new double[device.maxNumOfJointsInDevices];
4007  auto* t_max = new double[device.maxNumOfJointsInDevices];
4008  bool ret = true;
4009  for(unsigned int d=0; d<device.subdevices.size(); d++)
4010  {
4011  SubDevice *p=device.getSubdevice(d);
4012  if(!p)
4013  {
4014  ret = false;
4015  break;
4016  }
4017 
4018  if( (p->iTorque) &&(ret = p->iTorque->getTorqueRanges(t_min, t_max)))
4019  {
4020  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
4021  {
4022  min[juser] = t_min[jdevice];
4023  max[juser] = t_max[jdevice];
4024  }
4025  }
4026  else
4027  {
4028  printError("getTorqueRanges", p->id, ret);
4029  ret = false;
4030  break;
4031  }
4032  }
4033 
4034  delete [] t_min;
4035  delete [] t_max;
4036  return ret;
4037 
4038 }
4039 
4040 bool ControlBoardWrapper::getImpedance(int j, double* stiff, double* damp)
4041 {
4042  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
4043  int subIndex=device.lut[j].deviceEntry;
4044 
4045  SubDevice *p=device.getSubdevice(subIndex);
4046  if (!p)
4047  return false;
4048 
4049  if (p->iImpedance)
4050  {
4051  return p->iImpedance->getImpedance(off+p->base, stiff, damp);
4052  }
4053 
4054  return false;
4055 }
4056 
4057 bool ControlBoardWrapper::getImpedanceOffset(int j, double* offset)
4058 {
4059  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
4060  int subIndex=device.lut[j].deviceEntry;
4061 
4062  SubDevice *p=device.getSubdevice(subIndex);
4063  if (!p)
4064  return false;
4065 
4066  if (p->iImpedance)
4067  {
4068  return p->iImpedance->getImpedanceOffset(off+p->base, offset);
4069  }
4070 
4071  return false;
4072 }
4073 
4074 bool ControlBoardWrapper::getCurrentImpedanceLimit(int j, double *min_stiff, double *max_stiff, double *min_damp, double *max_damp)
4075 {
4076  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
4077  int subIndex=device.lut[j].deviceEntry;
4078 
4079  SubDevice *p=device.getSubdevice(subIndex);
4080  if (!p)
4081  return false;
4082 
4083  if (p->iImpedance)
4084  {
4085  return p->iImpedance->getCurrentImpedanceLimit(off+p->base, min_stiff, max_stiff, min_damp, max_damp);
4086  }
4087 
4088  return false;
4089 }
4090 
4092 {
4093  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
4094  int subIndex=device.lut[j].deviceEntry;
4095 
4096  SubDevice *p=device.getSubdevice(subIndex);
4097  if (!p)
4098  return false;
4099 
4100  if (p->iMode)
4101  {
4102  return p->iMode->getControlMode(off+p->base, mode);
4103  }
4104  return false;
4105 }
4106 
4108 {
4109  int *all_mode = new int[device.maxNumOfJointsInDevices];
4110  bool ret = true;
4111  for(unsigned int d=0; d<device.subdevices.size(); d++)
4112  {
4113  SubDevice *p=device.getSubdevice(d);
4114  if(!p)
4115  {
4116  ret = false;
4117  break;
4118  }
4119 
4120  if( (p->iMode) &&(ret = p->iMode->getControlModes(all_mode)))
4121  {
4122  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
4123  {
4124  modes[juser] = all_mode[jdevice];
4125  }
4126  }
4127  else
4128  {
4129  printError("getControlModes", p->id, ret);
4130  ret = false;
4131  break;
4132  }
4133  }
4134 
4135  delete [] all_mode;
4136  return ret;
4137 
4138 }
4139 
4140 // iControlMode2
4141 bool ControlBoardWrapper::getControlModes(const int n_joint, const int *joints, int *modes)
4142 {
4143  bool ret=true;
4144 
4145  for(int l=0; l<n_joint; l++)
4146  {
4147  int off=device.lut[joints[l]].offset;
4148  int subIndex=device.lut[joints[l]].deviceEntry;
4149 
4150  SubDevice *p=device.getSubdevice(subIndex);
4151  if (!p)
4152  return false;
4153 
4154  if (p->iMode)
4155  {
4156  ret=ret&&p->iMode->getControlMode(off+p->base, &modes[l]);
4157  }
4158  else
4159  ret=false;
4160  }
4161  return ret;
4162 }
4163 
4164 bool ControlBoardWrapper::setControlMode(const int j, const int mode)
4165 {
4166  bool ret = true;
4167  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
4168  int subIndex=device.lut[j].deviceEntry;
4169 
4170  SubDevice *p=device.getSubdevice(subIndex);
4171  if (!p)
4172  return false;
4173 
4174  if (p->iMode)
4175  {
4176  ret = p->iMode->setControlMode(off+p->base, mode);
4177  }
4178  return ret;
4179 }
4180 
4181 bool ControlBoardWrapper::setControlModes(const int n_joints, const int *joints, int *modes)
4182 {
4183  bool ret = true;
4184 
4185  rpcDataMutex.lock();
4186  //Reset subdev_jointsVectorLen vector
4187  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
4188 
4189  // Create a map of joints for each subDevice
4190  int subIndex = 0;
4191  for(int j=0; j<n_joints; j++)
4192  {
4193  subIndex = device.lut[joints[j]].deviceEntry;
4194  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[joints[j]].offset + rpcData.subdevices_p[subIndex]->base;
4195  rpcData.modes[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = modes[j];
4196  rpcData.subdev_jointsVectorLen[subIndex]++;
4197  }
4198 
4199  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
4200  {
4201  if(rpcData.subdevices_p[subIndex]->iMode)
4202  {
4203  ret= ret && rpcData.subdevices_p[subIndex]->iMode->setControlModes(rpcData.subdev_jointsVectorLen[subIndex],
4204  rpcData.jointNumbers[subIndex],
4205  rpcData.modes[subIndex]);
4206  }
4207  else
4208  {
4209  ret=false;
4210  }
4211  }
4212  rpcDataMutex.unlock();
4213  return ret;
4214 }
4215 
4217 {
4218  bool ret = true;
4219  int j_wrap = 0; // index of the wrapper joint
4220 
4221  int nDev = device.subdevices.size();
4222  for(int subDev_idx=0; subDev_idx < nDev; subDev_idx++)
4223  {
4224  int subIndex=device.lut[j_wrap].deviceEntry;
4225  SubDevice *p = device.getSubdevice(subIndex);
4226  if(!p) {
4227  return false;
4228  }
4229 
4230  int wrapped_joints=(p->top - p->base) + 1;
4231  int *joints = new int[wrapped_joints];
4232 
4233  if(p->iMode)
4234  {
4235  // versione comandi su subset di giunti
4236  for(int j_dev = 0; j_dev < wrapped_joints; j_dev++)
4237  {
4238  joints[j_dev] = p->base + j_dev; // for all joints is equivalent to add offset term
4239  }
4240 
4241  ret = ret && p->iMode->setControlModes(wrapped_joints, joints, &modes[j_wrap]);
4242  j_wrap+=wrapped_joints;
4243  }
4244 
4245  if(joints!=nullptr)
4246  {
4247  delete [] joints;
4248  joints = nullptr;
4249  }
4250  }
4251 
4252  return ret;
4253 }
4254 
4255 bool ControlBoardWrapper::setPosition(int j, double ref)
4256 {
4257  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
4258  int subIndex=device.lut[j].deviceEntry;
4259 
4260  SubDevice *p=device.getSubdevice(subIndex);
4261  if (!p)
4262  return false;
4263 
4264  if (p->posDir)
4265  {
4266  return p->posDir->setPosition(off+p->base, ref);
4267  }
4268 
4269  return false;
4270 }
4271 
4272 bool ControlBoardWrapper::setPositions(const int n_joints, const int *joints, const double *dpos)
4273 {
4274  bool ret = true;
4275 
4276  rpcDataMutex.lock();
4277  //Reset subdev_jointsVectorLen vector
4278  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
4279 
4280  // Create a map of joints for each subDevice
4281  int subIndex = 0;
4282  for(int j=0; j<n_joints; j++)
4283  {
4284  subIndex = device.lut[joints[j]].deviceEntry;
4285  int offset = device.lut[joints[j]].offset;
4286  int base = rpcData.subdevices_p[subIndex]->base;
4287  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = offset + base;
4288  rpcData.values[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = dpos[j];
4289  rpcData.subdev_jointsVectorLen[subIndex]++;
4290  }
4291 
4292  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
4293  {
4294  if(rpcData.subdevices_p[subIndex]->posDir) // Position Direct
4295  {
4296  ret= ret && rpcData.subdevices_p[subIndex]->posDir->setPositions(rpcData.subdev_jointsVectorLen[subIndex],
4297  rpcData.jointNumbers[subIndex],
4298  rpcData.values[subIndex]);
4299  }
4300  else
4301  {
4302  ret=false;
4303  }
4304  }
4305  rpcDataMutex.unlock();
4306  return ret;
4307 }
4308 
4309 bool ControlBoardWrapper::setPositions(const double *refs)
4310 {
4311  bool ret=true;
4312 
4313  for(int l=0;l<controlledJoints;l++)
4314  {
4315  int off=device.lut[l].offset;
4316  int subIndex=device.lut[l].deviceEntry;
4317 
4318  SubDevice *p=device.getSubdevice(subIndex);
4319  if (!p)
4320  return false;
4321 
4322  if (p->posDir)
4323  {
4324  ret = p->posDir->setPosition(off+p->base, refs[l]) && ret;
4325  }
4326  else
4327  ret=false;
4328  }
4329  return ret;
4330 }
4331 
4333  timeMutex.lock();
4334  yarp::os::Stamp ret=time;
4335  timeMutex.unlock();
4336  return ret;
4337 }
4338 
4339 bool ControlBoardWrapper::getRefPosition(const int j, double* ref)
4340 {
4341  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
4342  int subIndex=device.lut[j].deviceEntry;
4343 
4344  SubDevice *p=device.getSubdevice(subIndex);
4345 
4346  if (!p)
4347  return false;
4348 
4349  if (p->posDir)
4350  {
4351  bool ret = p->posDir->getRefPosition(off+p->base, ref);
4352  return ret;
4353  }
4354  *ref=0;
4355  return false;
4356 }
4357 
4359 {
4360  auto* references = new double[device.maxNumOfJointsInDevices];
4361  bool ret = true;
4362  for(unsigned int d=0; d<device.subdevices.size(); d++)
4363  {
4364  SubDevice *p=device.getSubdevice(d);
4365  if(!p)
4366  {
4367  ret = false;
4368  break;
4369  }
4370 
4371  if( (p->posDir) &&(ret = p->posDir->getRefPositions(references)))
4372  {
4373  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
4374  {
4375  spds[juser] = references[jdevice];
4376  }
4377  }
4378  else
4379  {
4380  printError("getRefPositions", p->id, ret);
4381  ret = false;
4382  break;
4383  }
4384  }
4385 
4386  delete [] references;
4387  return ret;
4388 
4389 }
4390 
4391 
4392 bool ControlBoardWrapper::getRefPositions(const int n_joints, const int *joints, double *targets)
4393 {
4394  bool ret = true;
4395 
4396  rpcDataMutex.lock();
4397  //Reset subdev_jointsVectorLen vector
4398  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
4399 
4400  // Create a map of joints for each subDevice
4401  int subIndex = 0;
4402  for(int j=0; j<n_joints; j++)
4403  {
4404  subIndex = device.lut[joints[j]].deviceEntry;
4405  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[joints[j]].offset + rpcData.subdevices_p[subIndex]->base;
4406  rpcData.subdev_jointsVectorLen[subIndex]++;
4407  }
4408 
4409  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
4410  {
4411  if(rpcData.subdevices_p[subIndex]->posDir)
4412  {
4413  ret= ret && rpcData.subdevices_p[subIndex]->posDir->getRefPositions( rpcData.subdev_jointsVectorLen[subIndex],
4414  rpcData.jointNumbers[subIndex],
4415  rpcData.values[subIndex]);
4416  }
4417  }
4418 
4419  if(ret)
4420  {
4421  // ReMix values by user expectations
4422  for(int i=0; i<rpcData.deviceNum; i++)
4423  rpcData.subdev_jointsVectorLen[i]=0; // reset tmp index
4424 
4425  // fill the output vector
4426  for(int j=0; j<n_joints; j++)
4427  {
4428  subIndex = device.lut[joints[j]].deviceEntry;
4429  targets[j] = rpcData.values[subIndex][rpcData.subdev_jointsVectorLen[subIndex]];
4430  rpcData.subdev_jointsVectorLen[subIndex]++;
4431  }
4432  }
4433  else
4434  {
4435  for(int j=0; j<n_joints; j++)
4436  {
4437  targets[j] = 0;
4438  }
4439  }
4440  rpcDataMutex.unlock();
4441  return ret;
4442 }
4443 
4444 
4445 //
4446 // IVelocityControl2 Interface
4447 //
4448 bool ControlBoardWrapper::velocityMove(const int n_joints, const int *joints, const double *spds)
4449 {
4450  bool ret = true;
4451 
4452  rpcDataMutex.lock();
4453  //Reset subdev_jointsVectorLen vector
4454  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
4455 
4456  // Create a map of joints for each subDevice
4457  int subIndex = 0;
4458  for(int j=0; j<n_joints; j++)
4459  {
4460  subIndex = device.lut[joints[j]].deviceEntry;
4461  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[joints[j]].offset + rpcData.subdevices_p[subIndex]->base;
4462  rpcData.values[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = spds[j];
4463  rpcData.subdev_jointsVectorLen[subIndex]++;
4464  }
4465 
4466  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
4467  {
4468  if(rpcData.subdevices_p[subIndex]->vel)
4469  {
4470  ret= ret && rpcData.subdevices_p[subIndex]->vel->velocityMove(rpcData.subdev_jointsVectorLen[subIndex],
4471  rpcData.jointNumbers[subIndex],
4472  rpcData.values[subIndex]);
4473  }
4474  else
4475  {
4476  ret=false;
4477  }
4478  }
4479  rpcDataMutex.unlock();
4480  return ret;
4481 }
4482 
4483 bool ControlBoardWrapper::getRefVelocity(const int j, double* vel)
4484 {
4485  if(verbose())
4487 
4488  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
4489  int subIndex=device.lut[j].deviceEntry;
4490 
4491  SubDevice *p=device.getSubdevice(subIndex);
4492 
4493  if (!p)
4494  return false;
4495 
4496  if (p->vel)
4497  {
4498  bool ret = p->vel->getRefVelocity(off+p->base, vel);
4499  return ret;
4500  }
4501  *vel=0;
4502  return false;
4503 }
4504 
4505 
4507 {
4508  auto* references = new double[device.maxNumOfJointsInDevices];
4509  bool ret = true;
4510  for(unsigned int d=0; d<device.subdevices.size(); d++)
4511  {
4512  SubDevice *p=device.getSubdevice(d);
4513  if(!p)
4514  {
4515  ret = false;
4516  break;
4517  }
4518 
4519  if( (p->vel) &&(ret = p->vel->getRefVelocities(references)))
4520  {
4521  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
4522  {
4523  vels[juser] = references[jdevice];
4524  }
4525  }
4526  else
4527  {
4528  printError("getRefVelocities", p->id, ret);
4529  ret = false;
4530  break;
4531  }
4532  }
4533 
4534  delete [] references;
4535  return ret;
4536 
4537 }
4538 
4539 bool ControlBoardWrapper::getRefVelocities(const int n_joints, const int* joints, double* vels)
4540 {
4541  if(verbose())
4543 
4544  bool ret = true;
4545 
4546  rpcDataMutex.lock();
4547  //Reset subdev_jointsVectorLen vector
4548  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
4549 
4550  // Create a map of joints for each subDevice
4551  int subIndex = 0;
4552  for(int j=0; j<n_joints; j++)
4553  {
4554  subIndex = device.lut[joints[j]].deviceEntry;
4555  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[joints[j]].offset + rpcData.subdevices_p[subIndex]->base;
4556  rpcData.subdev_jointsVectorLen[subIndex]++;
4557  }
4558 
4559  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
4560  {
4561  if(rpcData.subdevices_p[subIndex]->vel)
4562  {
4563  ret= ret && rpcData.subdevices_p[subIndex]->vel->getRefVelocities( rpcData.subdev_jointsVectorLen[subIndex],
4564  rpcData.jointNumbers[subIndex],
4565  rpcData.values[subIndex]);
4566  }
4567  }
4568 
4569  if(ret)
4570  {
4571  // ReMix values by user expectations
4572  for(int i=0; i<rpcData.deviceNum; i++)
4573  rpcData.subdev_jointsVectorLen[i]=0; // reset tmp index
4574 
4575  // fill the output vector
4576  for(int j=0; j<n_joints; j++)
4577  {
4578  subIndex = device.lut[joints[j]].deviceEntry;
4579  vels[j] = rpcData.values[subIndex][rpcData.subdev_jointsVectorLen[subIndex]];
4580  rpcData.subdev_jointsVectorLen[subIndex]++;
4581  }
4582  }
4583  else
4584  {
4585  for(int j=0; j<n_joints; j++)
4586  {
4587  vels[j] = 0;
4588  }
4589  }
4590  rpcDataMutex.unlock();
4591  return ret;
4592 }
4593 
4595 {
4596  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
4597  int subIndex=device.lut[j].deviceEntry;
4598 
4599  SubDevice *s=device.getSubdevice(subIndex);
4600  if (!s)
4601  return false;
4602 
4603  if (s->iInteract)
4604  {
4605  return s->iInteract->getInteractionMode(off+s->base, mode);
4606  }
4607  return false;
4608 }
4609 
4611 {
4612  bool ret = true;
4613 
4614  rpcDataMutex.lock();
4615  //Reset subdev_jointsVectorLen vector
4616  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
4617 
4618  // Create a map of joints for each subDevice
4619  int subIndex = 0;
4620  for(int j=0; j<n_joints; j++)
4621  {
4622  subIndex = device.lut[joints[j]].deviceEntry;
4623  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[joints[j]].offset + rpcData.subdevices_p[subIndex]->base;
4624  rpcData.subdev_jointsVectorLen[subIndex]++;
4625  }
4626 
4627  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
4628  {
4629  if(rpcData.subdevices_p[subIndex]->iInteract)
4630  {
4631  ret= ret && rpcData.subdevices_p[subIndex]->iInteract->getInteractionModes(rpcData.subdev_jointsVectorLen[subIndex],
4632  rpcData.jointNumbers[subIndex],
4633  (yarp::dev::InteractionModeEnum*) rpcData.modes[subIndex]);
4634  }
4635  else
4636  {
4637  ret=false;
4638  }
4639  }
4640 
4641  if(ret)
4642  {
4643  // ReMix values by user expectations
4644  for(int i=0; i<rpcData.deviceNum; i++)
4645  rpcData.subdev_jointsVectorLen[i]=0; // reset tmp index
4646 
4647  // fill the output vector
4648  for(int j=0; j<n_joints; j++)
4649  {
4650  subIndex = device.lut[joints[j]].deviceEntry;
4651  modes[j] = (yarp::dev::InteractionModeEnum) rpcData.modes[subIndex][rpcData.subdev_jointsVectorLen[subIndex]];
4652  rpcData.subdev_jointsVectorLen[subIndex]++;
4653  }
4654  }
4655  else
4656  {
4657  for(int j=0; j<n_joints; j++)
4658  {
4659  modes[j] = VOCAB_IM_UNKNOWN;
4660  }
4661  }
4662  rpcDataMutex.unlock();
4663  return ret;
4664 }
4665 
4667 {
4668 
4669  auto* imodes = new yarp::dev::InteractionModeEnum[device.maxNumOfJointsInDevices];
4670  bool ret = true;
4671  for(unsigned int d=0; d<device.subdevices.size(); d++)
4672  {
4673  SubDevice *p=device.getSubdevice(d);
4674  if(!p)
4675  {
4676  ret = false;
4677  break;
4678  }
4679 
4680  if( (p->iInteract) &&(ret = p->iInteract->getInteractionModes(imodes)))
4681  {
4682  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
4683  {
4684  modes[juser] = imodes[jdevice];
4685  }
4686  }
4687  else
4688  {
4689  printError("getInteractionModes", p->id, ret);
4690  ret = false;
4691  break;
4692  }
4693  }
4694 
4695  delete [] imodes;
4696  return ret;
4697 }
4698 
4700 {
4701  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
4702  int subIndex=device.lut[j].deviceEntry;
4703 
4704  SubDevice *s=device.getSubdevice(subIndex);
4705  if (!s)
4706  return false;
4707 
4708  if (s->iInteract)
4709  {
4710  return s->iInteract->setInteractionMode(off+s->base, mode);
4711  }
4712  return false;
4713 }
4714 
4716 {
4717  bool ret = true;
4718 
4719  rpcDataMutex.lock();
4720  //Reset subdev_jointsVectorLen vector
4721  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
4722 
4723  // Create a map of joints for each subDevice
4724  int subIndex = 0;
4725  for(int j=0; j<n_joints; j++)
4726  {
4727  subIndex = device.lut[joints[j]].deviceEntry;
4728  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[joints[j]].offset + rpcData.subdevices_p[subIndex]->base;
4729  rpcData.modes[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = (int) modes[j];
4730  rpcData.subdev_jointsVectorLen[subIndex]++;
4731  }
4732 
4733  for(subIndex=0; subIndex<rpcData.deviceNum; subIndex++)
4734  {
4735  if(rpcData.subdevices_p[subIndex]->iInteract)
4736  {
4737  ret= ret && rpcData.subdevices_p[subIndex]->iInteract->setInteractionModes( rpcData.subdev_jointsVectorLen[subIndex],
4738  rpcData.jointNumbers[subIndex],
4739  (yarp::dev::InteractionModeEnum*) rpcData.modes[subIndex]);
4740  }
4741  else
4742  {
4743  ret=false;
4744  }
4745  }
4746  rpcDataMutex.unlock();
4747  return ret;
4748 }
4749 
4751 {
4752  bool ret = true;
4753 
4754  for(int j=0; j<controlledJoints; j++)
4755  {
4756  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
4757  int subIndex=device.lut[j].deviceEntry;
4758 
4759  SubDevice *p=device.getSubdevice(subIndex);
4760  if (!p)
4761  return false;
4762 
4763  if (p->iInteract)
4764  {
4765  ret=ret && p->iInteract->setInteractionMode(off+p->base, modes[j]);
4766  }
4767  else
4768  ret=false;
4769  }
4770  return ret;
4771 }
4772 
4774 {
4775  int off; try{ off = device.lut.at(j).offset; }
4776  catch (...){ yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
4777  int subIndex = device.lut[j].deviceEntry;
4778 
4779  SubDevice *p = device.getSubdevice(subIndex);
4780  if (!p)
4781  return false;
4782 
4783  if (p->iPWM)
4784  {
4785  return p->iPWM->setRefDutyCycle(off + p->base, v);
4786  }
4787  return false;
4788 }
4789 
4791 {
4792  bool ret = true;
4793 
4794  for (int l = 0; l<controlledJoints; l++)
4795  {
4796  int off = device.lut[l].offset;
4797  int subIndex = device.lut[l].deviceEntry;
4798 
4799  SubDevice *p = device.getSubdevice(subIndex);
4800  if (!p)
4801  return false;
4802 
4803  if (p->iPWM)
4804  {
4805  ret = ret&&p->iPWM->setRefDutyCycle(off + p->base, v[l]);
4806  }
4807  else
4808  ret = false;
4809  }
4810  return ret;
4811 }
4812 
4814 {
4815  int off; try{ off = device.lut.at(j).offset; }
4816  catch (...){ yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
4817  int subIndex = device.lut[j].deviceEntry;
4818 
4819  SubDevice *p = device.getSubdevice(subIndex);
4820  if (!p)
4821  return false;
4822 
4823  if (p->iPWM)
4824  {
4825  return p->iPWM->getRefDutyCycle(off + p->base, v);
4826  }
4827  return false;
4828 }
4829 
4831 {
4832  auto* references = new double[device.maxNumOfJointsInDevices];
4833  bool ret = true;
4834  for(unsigned int d=0; d<device.subdevices.size(); d++)
4835  {
4836  SubDevice *p=device.getSubdevice(d);
4837  if(!p)
4838  {
4839  ret = false;
4840  break;
4841  }
4842 
4843  if( (p->iPWM) &&(ret = p->iPWM->getRefDutyCycles(references)))
4844  {
4845  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
4846  {
4847  v[juser] = references[jdevice];
4848  }
4849  }
4850  else
4851  {
4852  printError("getRefDutyCycles", p->id, ret);
4853  ret = false;
4854  break;
4855  }
4856  }
4857 
4858  delete [] references;
4859  return ret;
4860 
4861 }
4862 
4864 {
4865  int off; try{ off = device.lut.at(j).offset; }
4866  catch (...){ yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
4867  int subIndex = device.lut[j].deviceEntry;
4868 
4869  SubDevice *p = device.getSubdevice(subIndex);
4870  if (!p)
4871  return false;
4872 
4873  if (p->iPWM)
4874  {
4875  return p->iPWM->getDutyCycle(off + p->base, v);
4876  }
4877  return false;
4878 }
4879 
4881 {
4882  auto* dutyCicles = new double[device.maxNumOfJointsInDevices];
4883  bool ret = true;
4884  for(unsigned int d=0; d<device.subdevices.size(); d++)
4885  {
4886  SubDevice *p=device.getSubdevice(d);
4887  if(!p)
4888  {
4889  ret = false;
4890  break;
4891  }
4892 
4893  if( (p->iPWM) &&(ret = p->iPWM->getDutyCycles(dutyCicles)))
4894  {
4895  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
4896  {
4897  v[juser] = dutyCicles[jdevice];
4898  }
4899  }
4900  else
4901  {
4902  printError("getDutyCycles", p->id, ret);
4903  ret = false;
4904  break;
4905  }
4906  }
4907 
4908  delete [] dutyCicles;
4909  return ret;
4910 
4911 }
4912 
4913 
4914 //
4915 // ICurrentControl Interface
4916 //
4917 
4918 //bool ControlBoardWrapper::getAxes(int *ax);
4919 
4921 {
4922  auto* currs = new double[device.maxNumOfJointsInDevices];
4923  bool ret = true;
4924  for(unsigned int d=0; d<device.subdevices.size(); d++)
4925  {
4926  ret = false;
4927  SubDevice *p=device.getSubdevice(d);
4928  if(!p)
4929  {
4930  break;
4931  }
4932 
4933  if(p->iCurr)
4934  {
4935  ret = p->iCurr->getCurrents(currs);
4936  }
4937  else if(p->amp)
4938  {
4939  ret = p->amp->getCurrents(currs);
4940  }
4941 
4942  if(ret)
4943  {
4944  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
4945  {
4946  vals[juser] = currs[jdevice];
4947  }
4948  }
4949  else
4950  {
4951  printError("getCurrents", p->id, ret);
4952  break;
4953  }
4954  }
4955  delete [] currs;
4956  return ret;
4957 }
4958 
4959 bool ControlBoardWrapper::getCurrent(int j, double *val)
4960 {
4961  int off; try { off = device.lut.at(j).offset; } catch(...) { yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
4962  int subIndex=device.lut[j].deviceEntry;
4963 
4964  SubDevice *p=device.getSubdevice(subIndex);
4965  if (!p)
4966  return false;
4967 
4968  if (p->iCurr)
4969  {
4970  return p->iCurr->getCurrent(off+p->base,val);
4971  }
4972  else if (p->amp)
4973  {
4974  return p->amp->getCurrent(off+p->base,val);
4975  }
4976  *val=0.0;
4977  return false;
4978 }
4979 
4980 bool ControlBoardWrapper::getCurrentRange(int j, double *min, double *max)
4981 {
4982  int off; try{ off = device.lut.at(j).offset; }
4983  catch (...){ yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
4984  int subIndex = device.lut[j].deviceEntry;
4985 
4986  SubDevice *p = device.getSubdevice(subIndex);
4987  if (!p)
4988  return false;
4989 
4990  if (p->iCurr)
4991  {
4992  return p->iCurr->getCurrentRange(off + p->base, min, max);
4993  }
4994 
4995  return false;
4996 }
4997 
4998 bool ControlBoardWrapper::getCurrentRanges(double *min, double *max)
4999 {
5000  auto* c_min = new double[device.maxNumOfJointsInDevices];
5001  auto* c_max = new double[device.maxNumOfJointsInDevices];
5002  bool ret = true;
5003  for(unsigned int d=0; d<device.subdevices.size(); d++)
5004  {
5005  SubDevice *p=device.getSubdevice(d);
5006  if(!p)
5007  {
5008  ret = false;
5009  break;
5010  }
5011 
5012  if( (p->iCurr) &&(ret = p->iCurr->getCurrentRanges(c_min, c_max)))
5013  {
5014  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
5015  {
5016  min[juser] = c_min[jdevice];
5017  max[juser] = c_max[jdevice];
5018  }
5019  }
5020  else
5021  {
5022  printError("getCurrentRanges", p->id, ret);
5023  ret = false;
5024  break;
5025  }
5026  }
5027 
5028  delete [] c_min;
5029  delete [] c_max;
5030  return ret;
5031 
5032 }
5033 
5035 {
5036  bool ret = true;
5037 
5038  for (int l = 0; l<controlledJoints; l++)
5039  {
5040  int off = device.lut[l].offset;
5041  int subIndex = device.lut[l].deviceEntry;
5042 
5043  SubDevice *p = device.getSubdevice(subIndex);
5044  if (!p)
5045  return false;
5046 
5047  if (p->iCurr)
5048  {
5049  ret = ret&&p->iCurr->setRefCurrent(off + p->base, t[l]);
5050  }
5051  else
5052  ret = false;
5053  }
5054  return ret;
5055 }
5056 
5058 {
5059  int off; try{ off = device.lut.at(j).offset; }
5060  catch (...){ yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
5061  int subIndex = device.lut[j].deviceEntry;
5062 
5063  SubDevice *p = device.getSubdevice(subIndex);
5064  if (!p)
5065  return false;
5066 
5067  if (p->iCurr)
5068  {
5069  return p->iCurr->setRefCurrent(off + p->base, t);
5070  }
5071  return false;
5072 }
5073 
5074 bool ControlBoardWrapper::setRefCurrents(const int n_joint, const int *joints, const double *t)
5075 {
5076  bool ret = true;
5077 
5078  rpcDataMutex.lock();
5079  //Reset subdev_jointsVectorLen vector
5080  memset(rpcData.subdev_jointsVectorLen, 0x00, sizeof(int) * rpcData.deviceNum);
5081 
5082  // Create a map of joints for each subDevice
5083  int subIndex = 0;
5084  for (int j = 0; j<n_joint; j++)
5085  {
5086  subIndex = device.lut[joints[j]].deviceEntry;
5087  rpcData.jointNumbers[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = device.lut[joints[j]].offset + rpcData.subdevices_p[subIndex]->base;
5088  rpcData.values[subIndex][rpcData.subdev_jointsVectorLen[subIndex]] = t[j];
5089  rpcData.subdev_jointsVectorLen[subIndex]++;
5090  }
5091 
5092  for (subIndex = 0; subIndex<rpcData.deviceNum; subIndex++)
5093  {
5094  if (rpcData.subdevices_p[subIndex]->iCurr)
5095  {
5096  ret = ret && rpcData.subdevices_p[subIndex]->iCurr->setRefCurrents(rpcData.subdev_jointsVectorLen[subIndex],
5097  rpcData.jointNumbers[subIndex],
5098  rpcData.values[subIndex]);
5099  }
5100  else
5101  {
5102  ret = false;
5103  }
5104  }
5105  rpcDataMutex.unlock();
5106  return ret;
5107 }
5108 
5110 {
5111  auto* references = new double[device.maxNumOfJointsInDevices];
5112  bool ret = true;
5113  for(unsigned int d=0; d<device.subdevices.size(); d++)
5114  {
5115  SubDevice *p=device.getSubdevice(d);
5116  if(!p)
5117  {
5118  ret = false;
5119  break;
5120  }
5121 
5122  if( (p->iCurr) &&(ret = p->iCurr->getRefCurrents(references)))
5123  {
5124  for(int juser= p->wbase, jdevice=p->base; juser<=p->wtop; juser++, jdevice++)
5125  {
5126  t[juser] = references[jdevice];
5127  }
5128  }
5129  else
5130  {
5131  printError("getRefCurrents", p->id, ret);
5132  ret = false;
5133  break;
5134  }
5135  }
5136 
5137  delete [] references;
5138  return ret;
5139 
5140 }
5141 
5143 {
5144  int off; try{ off = device.lut.at(j).offset; }
5145  catch (...){ yCError(CONTROLBOARDWRAPPER, "Joint number %d out of bound [0-%d] for part %s", j, controlledJoints, partName.c_str()); return false; }
5146  int subIndex = device.lut[j].deviceEntry;
5147 
5148  SubDevice *p = device.getSubdevice(subIndex);
5149  if (!p)
5150  return false;
5151 
5152  if (p->iCurr)
5153  {
5154  return p->iCurr->getRefCurrent(off + p->base, t);
5155  }
5156 
5157  return false;
5158 }
const yarp::os::LogComponent & CONTROLBOARDWRAPPER()
float t
constexpr yarp::conf::vocab32_t VOCAB_CM_IDLE
Definition: IControlMode.h:126
bool ret
bool getRefDutyCycle(int j, double *v) override
Gets the last reference sent using the setRefDutyCycle function.
bool getImpedance(int j, double *stiff, double *damp) override
Get current impedance gains (stiffness,damping,offset) for a specific joint.
bool getControlMode(int j, int *mode) override
Get the current control mode.
bool getTargetPosition(const int joint, double *ref) override
Get the last position reference for the specified axis.
bool setControlModes(const int n_joints, const int *joints, int *modes) override
Set the current control mode for a subset of axes.
bool open(yarp::os::Searchable &prop) override
Open the device driver.
bool getTemperatures(double *vals) override
Get temperature of all the motors.
bool setEncoders(const double *vals) override
Set the value of all encoders.
bool setGearboxRatio(int m, const double val) override
Set the gearbox ratio for a specific motor.
bool setControlMode(const int j, const int mode) override
Set the current control mode.
bool getPidOutput(const yarp::dev::PidControlTypeEnum &pidtype, int j, double *out) override
Get the output of the controller (e.g.
bool enableAmp(int j) override
Enable the amplifier on a specific joint.
bool getCurrentRanges(double *min, double *max) override
Get the full scale of the current measurements for all motors motor (e.g.
bool getPWMLimit(int m, double *val) override
bool getTorques(double *t) override
Get the value of the torque for all joints (this is the feedback if you have torque sensors).
bool getLimits(int j, double *min, double *max) override
Get the software limits for a particular axis.
bool getAxes(int *ax) override
Get the number of controlled axes.
bool detachAll() override
Detach the object (you must have first called attach).
bool getNominalCurrent(int m, double *val) override
bool setRefCurrent(int j, double t) override
Set the reference value of the current for a single motor.
bool getEncoderTimed(int j, double *v, double *t) override
Read the instantaneous acceleration of all axes.
bool getMotorEncoderAccelerations(double *accs) override
Read the istantaneous acceleration of all axes.
bool getCurrentRange(int j, double *min, double *max) override
Get the full scale of the current measurement for a given motor (e.g.
bool getEncoderAccelerations(double *accs) override
Read the istantaneous acceleration of all axes.
bool setRefSpeed(int j, double sp) override
Set reference speed for a joint, this is the speed used during the interpolation of the trajectory.
bool disablePid(const yarp::dev::PidControlTypeEnum &pidtype, int j) override
Disable the pid computation for a joint.
bool verbose() const
Return the value of the verbose flag.
bool setRefCurrents(const double *t) override
Set the reference value of the currents for all motors.
bool getCurrents(double *vals) override
Read the electric current going to all motors.
bool getMotorEncoders(double *encs) override
Read the position of all axes.
bool getRefVelocity(const int joint, double *vel) override
Get the last reference speed set by velocityMove for single joint.
bool setPidReference(const yarp::dev::PidControlTypeEnum &pidtype, int j, double ref) override
Set the controller reference for a given axis.
bool getPowerSupplyVoltage(int m, double *val) override
bool setRefTorque(int j, double t) override
Set the reference value of the torque for a given joint.
bool setTemperatureLimit(int m, const double val) override
Set the temperature limit for a specific motor.
bool setRefDutyCycles(const double *v) override
Sets the reference dutycycle for all the motors.
bool getTemperatureLimit(int m, double *val) override
Retreives the current temperature limit for a specific motor.
bool relativeMove(int j, double delta) override
Set relative position.
bool getTemperature(int m, double *val) override
Get temperature of a motor.
bool getRefCurrents(double *t) override
Get the reference value of the currents for all motors.
bool setPids(const yarp::dev::PidControlTypeEnum &pidtype, const yarp::dev::Pid *ps) override
Set new pid value on multiple axes.
bool setRefTorques(const double *t) override
Set the reference value of the torque for all joints.
bool calibrateAxisWithParams(int j, unsigned int ui, double v1, double v2, double v3) override
Start calibration, this method is very often platform specific.
bool getMotorEncoderSpeeds(double *spds) override
Read the instantaneous speed of all axes.
bool getPids(const yarp::dev::PidControlTypeEnum &pidtype, yarp::dev::Pid *pids) override
Get current pid value for a specific joint.
bool getRefVelocities(double *vels) override
Get the last reference speed set by velocityMove for all joints.
bool positionMove(int j, double ref) override
Set new reference point for a single axis.
bool getMotorEncoder(int m, double *v) override
Read the value of an encoder.
bool resetMotorEncoder(int m) override
Reset encoder, single joint.
bool getMaxCurrent(int j, double *v) override
Returns the maximum electric current allowed for a given motor.
bool setEncoder(int j, double val) override
Set the value of the encoder for a given joint.
bool setImpedance(int j, double stiff, double damp) override
Set current impedance gains (stiffness,damping) for a specific joint.
bool getPidErrorLimit(const yarp::dev::PidControlTypeEnum &pidtype, int j, double *limit) override
Get the error limit for the controller on a specific joint.
bool getRefPosition(const int joint, double *ref) override
Get the last position reference for the specified axis.
bool abortCalibration() override
bool setRefDutyCycle(int j, double v) override
Sets the reference dutycycle to a single motor.
bool getRefPositions(double *refs) override
Get the last position reference for all axes.
bool getRefTorque(int j, double *t) override
Get the reference value of the torque for a given joint.
bool getDutyCycles(double *v) override
Gets the current dutycycle of the output of the amplifier (i.e.
bool getMotorTorqueParams(int j, yarp::dev::MotorTorqueParameters *params) override
Get a subset of motor parameters (bemf, ktau etc) useful for torque control.
bool setMotorEncoders(const double *vals) override
Set the value of all encoders.
bool getPidError(const yarp::dev::PidControlTypeEnum &pidtype, int j, double *err) override
Get the current error for a joint.
bool getPidReference(const yarp::dev::PidControlTypeEnum &pidtype, int j, double *ref) override
Get the current reference of the pid controller for a specific joint.
bool setPidReferences(const yarp::dev::PidControlTypeEnum &pidtype, const double *refs) override
Set the controller reference, multiple axes.
bool setMaxCurrent(int j, double v) override
Set the maximum electric current going to a given motor.
bool getAmpStatus(int *st) override
Get the status of the amplifiers, coded in a 32 bits integer for each amplifier (at the moment contai...
bool getRefCurrent(int j, double *t) override
Get the reference value of the current for a single motor.
bool setPWMLimit(int m, const double val) override
bool getMotorEncoderAcceleration(int m, double *acc) override
Read the instantaneous acceleration of an axis.
yarp::os::Stamp getLastInputStamp() override
Return the time stamp relative to the last acquisition.
bool getControlModes(int *modes) override
Get the current control mode (multiple joints).
bool getTorqueRange(int j, double *min, double *max) override
Get the full scale of the torque sensor of a given joint.
bool calibrateWholePart() override
calibrateWholePart: call the procedure for calibrating the whole device
bool velocityMove(int j, double v) override
Set new reference speed for a single axis.
bool quitCalibrate() override
quitCalibrate: interrupt the calibration procedure
bool getRefDutyCycles(double *v) override
Gets the last reference sent using the setRefDutyCycles function.
bool getEncodersTimed(double *encs, double *t) override
Read the instantaneous acceleration of all axes.
bool getDutyCycle(int j, double *v) override
Gets the current dutycycle of the output of the amplifier (i.e.
bool stop() override
Stop motion, multiple joints.
bool resetMotorEncoders() override
Reset encoders.
bool getInteractionMode(int j, yarp::dev::InteractionModeEnum *mode) override
Get the current interaction mode of the robot, values can be stiff or compliant.
bool enablePid(const yarp::dev::PidControlTypeEnum &pidtype, int j) override
Enable the pid computation for a joint.
bool getTargetPositions(double *refs) override
Get the last position reference for all axes.
bool getEncoderSpeed(int j, double *sp) override
Read the istantaneous speed of an axis.
bool getMotorEncoderSpeed(int m, double *sp) override
Read the istantaneous speed of an axis.
bool setMotorEncoderCountsPerRevolution(int m, const double cpr) override
Sets number of counts per revolution for motor encoder m.
bool getNumberOfMotors(int *num) override
Retrieves the number of controlled axes from the current physical interface.
bool setPeakCurrent(int m, const double val) override
bool setNominalCurrent(int m, const double val) override
bool setPidOffset(const yarp::dev::PidControlTypeEnum &pidtype, int j, double v) override
Set offset value for a given controller.
bool getMotorEncoderCountsPerRevolution(int m, double *cpr) override
gets number of counts per revolution for motor encoder m.
bool setPid(const yarp::dev::PidControlTypeEnum &pidtype, int j, const yarp::dev::Pid &p) override
Set new pid value for a joint axis.
yarp::dev::IRemoteCalibrator * getCalibratorDevice() override
getCalibratorDevice: return the pointer stored with the setCalibratorDevice
bool disableAmp(int j) override
Disable the amplifier on a specific joint.
bool getPidOutputs(const yarp::dev::PidControlTypeEnum &pidtype, double *outs) override
Get the output of the controllers (e.g.
bool parkSingleJoint(int j, bool _wait=true) override
parkSingleJoint(): start the parking procedure for the single joint
bool getImpedanceOffset(int j, double *offset) override
Get current force Offset for a specific joint.
bool setPosition(int j, double ref) override
Set new position for a single axis.
bool setInteractionModes(int n_joints, int *joints, yarp::dev::InteractionModeEnum *modes) override
Set the interaction mode of the robot for a set of joints, values can be stiff or compliant.
bool getRemoteVariable(std::string key, yarp::os::Bottle &val) override
bool resetPid(const yarp::dev::PidControlTypeEnum &pidtype, int j) override
Reset the controller of a given joint, usually sets the current status of the joint as the reference ...
bool getNumberOfMotorEncoders(int *num) override
Get the number of available motor encoders.
bool getTorque(int j, double *t) override
Get the value of the torque on a given joint (this is the feedback if you have a torque sensor).
bool calibrateSingleJoint(int j) override
calibrateSingleJoint: call the calibration procedure for the single joint
bool setRefSpeeds(const double *spds) override
Set reference speed on all joints.
bool getEncoders(double *encs) override
Read the position of all axes.
bool setLimits(int j, double min, double max) override
Set the software limits for a particular axis, the behavior of the control card when these limits are...
bool calibrationDone(int j) override
Check whether the calibration has been completed.
bool homingSingleJoint(int j) override
homingSingleJoint: call the homing procedure for a single joint
bool getRefAcceleration(int j, double *acc) override
Get reference acceleration for a joint.
bool getEncoder(int j, double *v) override
Read the value of an encoder.
bool setPidErrorLimits(const yarp::dev::PidControlTypeEnum &pidtype, const double *limits) override
Get the error limit for the controller on all joints.
bool checkMotionDone(int j, bool *flag) override
Check if the current trajectory is terminated.
bool setImpedanceOffset(int j, double offset) override
Set current force Offset for a specific joint.
bool getRemoteVariablesList(yarp::os::Bottle *listOfKeys) override
bool setRefAccelerations(const double *accs) override
Set reference acceleration on all joints.
bool homingWholePart() override
homingWholePart: call the homing procedure for a the whole part/device
bool getRefSpeed(int j, double *ref) override
Get reference speed for a joint.
bool getPid(const yarp::dev::PidControlTypeEnum &pidtype, int j, yarp::dev::Pid *p) override
Get current pid value for a specific joint.
bool isCalibratorDevicePresent(bool *isCalib) override
isCalibratorDevicePresent: check if a calibrator device has been set
bool getInteractionModes(int n_joints, int *joints, yarp::dev::InteractionModeEnum *modes) override
Get the current interaction mode of the robot for a set of joints, values can be stiff or compliant.
bool getPidErrors(const yarp::dev::PidControlTypeEnum &pidtype, double *errs) override
Get the error of all joints.
bool setMotorEncoder(int m, const double val) override
Set the value of the encoder for a given joint.
bool setInteractionMode(int j, yarp::dev::InteractionModeEnum mode) override
Set the interaction mode of the robot, values can be stiff or compliant.
bool getPWM(int m, double *val) override
bool getTorqueRanges(double *min, double *max) override
Get the full scale of the torque sensors of all joints.
bool getEncoderAcceleration(int j, double *acc) override
Read the instantaneous acceleration of an axis.
~ControlBoardWrapper() override
bool getRefSpeeds(double *spds) override
Get reference speed of all joints.
bool setPidErrorLimit(const yarp::dev::PidControlTypeEnum &pidtype, int j, double limit) override
Set the error limit for the controller on a specifi joint.
bool close() override
Close the device driver by deallocating all resources and closing ports.
bool getPidErrorLimits(const yarp::dev::PidControlTypeEnum &pidtype, double *limits) override
Get the error limit for all controllers.
bool resetEncoders() override
Reset encoders.
bool isPidEnabled(const yarp::dev::PidControlTypeEnum &pidtype, int j, bool *enabled) override
Get the current status (enabled/disabled) of the pid.
bool setCalibrationParameters(int j, const yarp::dev::CalibrationParameters &params) override
Start calibration, this method is very often platform specific.
bool getRefAccelerations(double *accs) override
Get reference acceleration of all joints.
bool resetEncoder(int j) override
Reset encoder, single joint.
bool getCurrent(int j, double *val) override
Read the electric current going to a given motor.
bool setMotorTorqueParams(int j, const yarp::dev::MotorTorqueParameters params) override
Set a subset of motor parameters (bemf, ktau etc) useful for torque control.
bool getMotorEncoderTimed(int m, double *v, double *t) override
Read the instantaneous position of a motor encoder.
bool setRefAcceleration(int j, double acc) override
Set reference acceleration for a joint.
bool getCurrentImpedanceLimit(int j, double *min_stiff, double *max_stiff, double *min_damp, double *max_damp) override
Get the current impedandance limits for a specific joint.
bool getEncoderSpeeds(double *spds) override
Read the instantaneous speed of all axes.
bool getJointType(int j, yarp::dev::JointTypeEnum &type) override
bool getPidReferences(const yarp::dev::PidControlTypeEnum &pidtype, double *refs) override
Get the current reference of all pid controllers.
bool setRemoteVariable(std::string key, const yarp::os::Bottle &val) override
bool parkWholePart() override
parkWholePart: start the parking procedure for the whole part
bool getPeakCurrent(int m, double *val) override
bool getGearboxRatio(int m, double *val) override
Get the gearbox ratio for a specific motor.
bool quitPark() override
quitPark: interrupt the park procedure
bool getAxisName(int j, std::string &name) override
bool setVelLimits(int j, double min, double max) override
Set the software velocity limits for a particular axis, the behavior of the control card when these l...
void run() override
The thread main loop deals with writing on ports here.
bool attachAll(const yarp::dev::PolyDriverList &l) override
Attach to a list of objects.
bool getVelLimits(int j, double *min, double *max) override
Get the software velocity limits for a particular axis.
bool getRefTorques(double *refs) override
Get the reference value of the torque for all joints.
bool setPositions(const int n_joints, const int *joints, const double *dpos) override
Set new reference point for all axes.
bool getMotorEncodersTimed(double *encs, double *t) override
Read the instantaneous position of all motor encoders.
void resize(int _deviceNum, int _maxJointsNumForDevice, WrappedDevice *_device)
SubDevice ** subdevices_p
void init(ControlBoardWrapper *x)
Initialization.
virtual bool initialize()
Initialize the internal data.
void init(ControlBoardWrapper *x)
Initialization.
void setVerbose(bool _verbose)
Definition: SubDevice.h:100
yarp::dev::IControlLimits * lim
Definition: SubDevice.h:77
yarp::dev::IImpedanceControl * iImpedance
Definition: SubDevice.h:81
bool configure(int wbase, int wtop, int base, int top, int axes, const std::string &id, ControlBoardWrapper *_parent)
Definition: SubDevice.cpp:55
yarp::dev::IMotorEncoders * iMotEnc
Definition: SubDevice.h:75
yarp::dev::IControlMode * iMode
Definition: SubDevice.h:82
std::string id
Definition: SubDevice.h:58
yarp::dev::IEncodersTimed * iJntEnc
Definition: SubDevice.h:74
yarp::dev::IVelocityControl * vel
Definition: SubDevice.h:73
yarp::dev::IAmplifierControl * amp
Definition: SubDevice.h:76
yarp::dev::IAxisInfo * info
Definition: SubDevice.h:83
yarp::dev::IMotor * imotor
Definition: SubDevice.h:86
yarp::dev::IInteractionMode * iInteract
Definition: SubDevice.h:85
yarp::dev::IPositionControl * pos
Definition: SubDevice.h:72
yarp::dev::ITorqueControl * iTorque
Definition: SubDevice.h:80
void detach()
Definition: SubDevice.cpp:94
yarp::dev::IPidControl * pid
Definition: SubDevice.h:71
int base
Definition: SubDevice.h:59
int top
Definition: SubDevice.h:60
int wbase
Definition: SubDevice.h:61
yarp::dev::IRemoteVariables * iVar
Definition: SubDevice.h:87
yarp::dev::IPWMControl * iPWM
Definition: SubDevice.h:88
yarp::dev::IPositionDirect * posDir
Definition: SubDevice.h:84
int totalAxis
Definition: SubDevice.h:64
yarp::dev::IControlCalibration * calib
Definition: SubDevice.h:78
yarp::dev::ICurrentControl * iCurr
Definition: SubDevice.h:89
std::vector< DevicesLutEntry > lut
Definition: SubDevice.h:126
SubDevice * getSubdevice(unsigned int i)
Definition: SubDevice.h:129
int maxNumOfJointsInDevices
Definition: SubDevice.h:127
SubDeviceVector subdevices
Definition: SubDevice.h:125
bool view(T *&x)
Get an interface to the device driver.
Definition: DeviceDriver.h:77
void attach(yarp::os::TypedReader< yarp::os::Bottle > &source)
Attach this object to a source of messages.
Definition: DeviceDriver.h:202
virtual bool getPWMLimit(int j, double *val)
virtual bool enableAmp(int j)=0
Enable the amplifier on a specific joint.
virtual bool setNominalCurrent(int m, const double val)
virtual bool getCurrents(double *vals)=0
virtual bool disableAmp(int j)=0
Disable the amplifier on a specific joint.
virtual bool getPWM(int j, double *val)
virtual bool getAmpStatus(int *st)=0
virtual bool setPWMLimit(int j, const double val)
virtual bool getMaxCurrent(int j, double *v)=0
Returns the maximum electric current allowed for a given motor.
virtual bool getNominalCurrent(int m, double *val)
virtual bool getCurrent(int j, double *val)=0
virtual bool getPowerSupplyVoltage(int j, double *val)
virtual bool setMaxCurrent(int j, double v)=0
virtual bool setPeakCurrent(int m, const double val)
virtual bool getPeakCurrent(int m, double *val)
virtual bool getAxisName(int axis, std::string &name)=0
virtual bool getJointType(int axis, yarp::dev::JointTypeEnum &type)
Definition: IAxisInfo.h:62
virtual bool setCalibrationParameters(int axis, const CalibrationParameters &params)
Start calibration, this method is very often platform specific.
virtual bool calibrationDone(int j)=0
Check if the calibration is terminated, on a particular joint.
virtual bool calibrateAxisWithParams(int axis, unsigned int type, double p1, double p2, double p3)=0
Start calibration, this method is very often platform specific.
virtual bool getVelLimits(int axis, double *min, double *max)=0
Get the software speed limits for a particular axis.
virtual bool getLimits(int axis, double *min, double *max)=0
Get the software limits for a particular axis.
virtual bool setLimits(int axis, double min, double max)=0
Set the software limits for a particular axis, the behavior of the control card when these limits are...
virtual bool setVelLimits(int axis, double min, double max)=0
Set the software speed limits for a particular axis, the behavior of the control card when these limi...
virtual bool setControlMode(const int j, const int mode)=0
Set the current control mode.
virtual bool setControlModes(const int n_joint, const int *joints, int *modes)=0
Set the current control mode for a subset of axes.
virtual bool getControlModes(int *modes)=0
Get the current control mode (multiple joints).
virtual bool getControlMode(int j, int *mode)=0
Get the current control mode.
virtual bool getCurrents(double *currs)=0
Get the instantaneous current measurement for all motors.
virtual bool setRefCurrent(int m, double curr)=0
Set the reference value of the current for a single motor.
virtual bool getRefCurrents(double *currs)=0
Get the reference value of the currents for all motors.
virtual bool setRefCurrents(const double *currs)=0
Set the reference value of the currents for all motors.
virtual bool getCurrent(int m, double *curr)=0
Get the instantaneous current measurement for a single motor.
virtual bool getCurrentRange(int m, double *min, double *max)=0
Get the full scale of the current measurement for a given motor (e.g.
virtual bool getRefCurrent(int m, double *curr)=0
Get the reference value of the current for a single motor.
virtual bool getCurrentRanges(double *min, double *max)=0
Get the full scale of the current measurements for all motors motor (e.g.
virtual bool getEncodersTimed(double *encs, double *time)=0
Read the instantaneous acceleration of all axes.
virtual bool getEncoderTimed(int j, double *encs, double *time)=0
Read the instantaneous acceleration of all axes.
Control board, encoder interface.
Definition: IEncoders.h:121
virtual bool getEncoderSpeed(int j, double *sp)=0
Read the istantaneous speed of an axis.
virtual bool getEncoderAccelerations(double *accs)=0
Read the instantaneous acceleration of all axes.
virtual bool setEncoder(int j, double val)=0
Set the value of the encoder for a given joint.
virtual bool getEncoder(int j, double *v)=0
Read the value of an encoder.
virtual bool resetEncoder(int j)=0
Reset encoder, single joint.
virtual bool getAxes(int *ax)=0
Get the number of controlled axes.
virtual bool getEncoders(double *encs)=0
Read the position of all axes.
virtual bool getEncoderSpeeds(double *spds)=0
Read the instantaneous speed of all axes.
virtual bool getEncoderAcceleration(int j, double *spds)=0
Read the instantaneous acceleration of an axis.
virtual bool setImpedance(int j, double stiffness, double damping)=0
Set current impedance gains (stiffness,damping) for a specific joint.
virtual bool getImpedanceOffset(int j, double *offset)=0
Get current force Offset for a specific joint.
virtual bool setImpedanceOffset(int j, double offset)=0
Set current force Offset for a specific joint.
virtual bool getImpedance(int j, double *stiffness, double *damping)=0
Get current impedance gains (stiffness,damping,offset) for a specific joint.
virtual bool getCurrentImpedanceLimit(int j, double *min_stiff, double *max_stiff, double *min_damp, double *max_damp)=0
Get the current impedandance limits for a specific joint.
virtual bool getInteractionMode(int axis, yarp::dev::InteractionModeEnum *mode)=0
Get the current interaction mode of the robot, values can be stiff or compliant.
virtual bool getInteractionModes(int n_joints, int *joints, yarp::dev::InteractionModeEnum *modes)=0
Get the current interaction mode of the robot for a set of joints, values can be stiff or compliant.
virtual bool setInteractionModes(int n_joints, int *joints, yarp::dev::InteractionModeEnum *modes)=0
Set the interaction mode of the robot for a set of joints, values can be stiff or compliant.
virtual bool setInteractionMode(int axis, yarp::dev::InteractionModeEnum mode)=0
Set the interaction mode of the robot, values can be stiff or compliant.
virtual bool getMotorEncodersTimed(double *encs, double *time)=0
Read the instantaneous position of all motor encoders.
virtual bool getMotorEncoderCountsPerRevolution(int m, double *cpr)=0
Gets number of counts per revolution for motor encoder m.
virtual bool setMotorEncoderCountsPerRevolution(int m, const double cpr)=0
Sets number of counts per revolution for motor encoder m.
virtual bool resetMotorEncoder(int m)=0
Reset motor encoder, single motor.
virtual bool getMotorEncoderSpeed(int m, double *sp)=0
Read the istantaneous speed of a motor encoder.
virtual bool getMotorEncoderSpeeds(double *spds)=0
Read the instantaneous speed of all motor encoders.
virtual bool getMotorEncoderTimed(int m, double *encs, double *time)=0
Read the instantaneous position of a motor encoder.
virtual bool getMotorEncoderAcceleration(int m, double *acc)=0
Read the instantaneous acceleration of a motor encoder.
virtual bool getMotorEncoderAccelerations(double *accs)=0
Read the instantaneous acceleration of all motor encoders.
virtual bool getMotorEncoders(double *encs)=0
Read the position of all motor encoders.
virtual bool setMotorEncoder(int m, const double val)=0
Set the value of the motor encoder for a given motor.
virtual bool getMotorEncoder(int m, double *v)=0
Read the value of a motor encoder.
virtual bool getTemperature(int m, double *val)=0
Get temperature of a motor.
virtual bool getTemperatures(double *vals)=0
Get temperature of all the motors.
virtual bool getTemperatureLimit(int m, double *temp)=0
Retreives the current temperature limit for a specific motor.
virtual bool getGearboxRatio(int m, double *val)
Get the gearbox ratio for a specific motor.
Definition: IMotor.h:152
virtual bool setTemperatureLimit(int m, const double temp)=0
Set the temperature limit for a specific motor.
virtual bool setGearboxRatio(int m, const double val)
Set the gearbox ratio for a specific motor.
Definition: IMotor.h:160
virtual bool getDutyCycle(int m, double *val)=0
Gets the current dutycycle of the output of the amplifier (i.e.
virtual bool getRefDutyCycles(double *refs)=0
Gets the last reference sent using the setRefDutyCycles function.
virtual bool setRefDutyCycle(int m, double ref)=0
Sets the reference dutycycle to a single motor.
virtual bool getRefDutyCycle(int m, double *ref)=0
Gets the last reference sent using the setRefDutyCycle function.
virtual bool getDutyCycles(double *vals)=0
Gets the current dutycycle of the output of the amplifier (i.e.
virtual bool setPid(const PidControlTypeEnum &pidtype, int j, const Pid &pid)=0
Set new pid value for a joint axis.
virtual bool getPidReference(const PidControlTypeEnum &pidtype, int j, double *ref)=0
Get the current reference of the pid controller for a specific joint.
virtual bool getPidOutput(const PidControlTypeEnum &pidtype, int j, double *out)=0
Get the output of the controller (e.g.
virtual bool getPidReferences(const PidControlTypeEnum &pidtype, double *refs)=0
Get the current reference of all pid controllers.
virtual bool resetPid(const PidControlTypeEnum &pidtype, int j)=0
Reset the controller of a given joint, usually sets the current status of the joint as the reference ...
virtual bool setPidOffset(const PidControlTypeEnum &pidtype, int j, double v)=0
Set offset value for a given controller.
virtual bool getPidErrorLimits(const PidControlTypeEnum &pidtype, double *limits)=0
Get the error limit for all controllers.
virtual bool getPidError(const PidControlTypeEnum &pidtype, int j, double *err)=0
Get the current error for a joint.
virtual bool getPidErrorLimit(const PidControlTypeEnum &pidtype, int j, double *limit)=0
Get the error limit for the controller on a specific joint.
virtual bool setPidErrorLimit(const PidControlTypeEnum &pidtype, int j, double limit)=0
Set the error limit for the controller on a specifi joint.
virtual bool disablePid(const PidControlTypeEnum &pidtype, int j)=0
Disable the pid computation for a joint.
virtual bool getPidOutputs(const PidControlTypeEnum &pidtype, double *outs)=0
Get the output of the controllers (e.g.
virtual bool setPidReference(const PidControlTypeEnum &pidtype, int j, double ref)=0
Set the controller reference for a given axis.
virtual bool getPidErrors(const PidControlTypeEnum &pidtype, double *errs)=0
Get the error of all joints.
virtual bool enablePid(const PidControlTypeEnum &pidtype, int j)=0
Enable the pid computation for a joint.
virtual bool isPidEnabled(const PidControlTypeEnum &pidtype, int j, bool *enabled)=0
Get the current status (enabled/disabled) of the pid.
virtual bool getPids(const PidControlTypeEnum &pidtype, Pid *pids)=0
Get current pid value for a specific joint.
virtual bool getPid(const PidControlTypeEnum &pidtype, int j, Pid *pid)=0
Get current pid value for a specific joint.
virtual bool getRefAcceleration(int j, double *acc)=0
Get reference acceleration for a joint.
virtual bool setRefSpeed(int j, double sp)=0
Set reference speed for a joint, this is the speed used during the interpolation of the trajectory.
virtual bool setRefAcceleration(int j, double acc)=0
Set reference acceleration for a joint.
virtual bool relativeMove(int j, double delta)=0
Set relative position.
virtual bool getTargetPosition(const int joint, double *ref)
Get the last position reference for the specified axis.
virtual bool setRefSpeeds(const double *spds)=0
Set reference speed on all joints.
virtual bool checkMotionDone(int j, bool *flag)=0
Check if the current trajectory is terminated.
virtual bool getRefSpeeds(double *spds)=0
Get reference speed of all joints.
virtual bool stop(int j)=0
Stop motion, single joint.
virtual bool setRefAccelerations(const double *accs)=0
Set reference acceleration on all joints.
virtual bool getRefAccelerations(double *accs)=0
Get reference acceleration of all joints.
virtual bool getRefSpeed(int j, double *ref)=0
Get reference speed for a joint.
virtual bool positionMove(int j, double ref)=0
Set new reference point for a single axis.
virtual bool getTargetPositions(double *refs)
Get the last position reference for all axes.
virtual bool getRefPositions(double *refs)
Get the last position reference for all axes.
virtual bool setPositions(const int n_joint, const int *joints, const double *refs)=0
Set new reference point for all axes.
virtual bool setPosition(int j, double ref)=0
Set new position for a single axis.
virtual bool getRefPosition(const int joint, double *ref)
Get the last position reference for the specified axis.
IRemoteCalibrator interface is meant to remotize the access of the calibration device in order to all...
virtual bool parkWholePart()=0
parkWholePart: start the parking procedure for the whole part
virtual bool homingSingleJoint(int j)=0
homingSingleJoint: call the homing procedure for a single joint
virtual bool isCalibratorDevicePresent(bool *isCalib)
isCalibratorDevicePresent: check if a calibrator device has been set
virtual bool homingWholePart()=0
homingWholePart: call the homing procedure for a the whole part/device
virtual bool quitPark()=0
quitPark: interrupt the park procedure
virtual bool parkSingleJoint(int j, bool _wait=true)=0
parkSingleJoint(): start the parking procedure for the single joint
virtual bool calibrateWholePart()=0
calibrateWholePart: call the procedure for calibrating the whole device
virtual bool quitCalibrate()=0
quitCalibrate: interrupt the calibration procedure
virtual yarp::dev::IRemoteCalibrator * getCalibratorDevice()
getCalibratorDevice: return the pointer stored with the setCalibratorDevice
virtual bool setRemoteVariable(std::string key, const yarp::os::Bottle &val)=0
virtual bool getRemoteVariable(std::string key, yarp::os::Bottle &val)=0
virtual bool getRemoteVariablesList(yarp::os::Bottle *listOfKeys)=0
virtual bool setRefTorque(int j, double t)=0
Set the reference value of the torque for a given joint.
virtual bool setRefTorques(const double *t)=0
Set the reference value of the torque for all joints.
virtual bool getRefTorques(double *t)=0
Get the reference value of the torque for all joints.
virtual bool setMotorTorqueParams(int j, const yarp::dev::MotorTorqueParameters params)
Set a subset of motor parameters (bemf, ktau etc) useful for torque control.
virtual bool getMotorTorqueParams(int j, yarp::dev::MotorTorqueParameters *params)
Get a subset of motor parameters (bemf, ktau etc) useful for torque control.
virtual bool getTorques(double *t)=0
Get the value of the torque for all joints (this is the feedback if you have torque sensors).
virtual bool getTorqueRange(int j, double *min, double *max)=0
Get the full scale of the torque sensor of a given joint.
virtual bool getTorqueRanges(double *min, double *max)=0
Get the full scale of the torque sensors of all joints.
virtual bool getRefTorque(int j, double *t)=0
Get the reference value of the torque for a given joint.
virtual bool getTorque(int j, double *t)=0
Get the value of the torque on a given joint (this is the feedback if you have a torque sensor).
virtual bool getRefVelocity(const int joint, double *vel)
Get the last reference speed set by velocityMove for single joint.
virtual bool velocityMove(int j, double sp)=0
Start motion at a given speed, single joint.
virtual bool getRefVelocities(double *vels)
Get the last reference speed set by velocityMove for all joints.
Contains the parameters for a PID.
A container for a device driver.
Definition: PolyDriver.h:27
bool close() override
Close the DeviceDriver.
Definition: PolyDriver.cpp:176
bool isValid() const
Check if device is valid.
Definition: PolyDriver.cpp:199
bool open(const std::string &txt)
Construct and configure a device by its common name.
Definition: PolyDriver.cpp:143
yarp::sig::VectorOf< double > motorVelocity
Definition: jointData.h:40
yarp::sig::VectorOf< double > jointAcceleration
Definition: jointData.h:36
yarp::sig::VectorOf< int > controlMode
Definition: jointData.h:50
yarp::sig::VectorOf< int > interactionMode
Definition: jointData.h:52
yarp::sig::VectorOf< double > current
Definition: jointData.h:48
yarp::sig::VectorOf< double > motorAcceleration
Definition: jointData.h:42
yarp::sig::VectorOf< double > motorPosition
Definition: jointData.h:38
yarp::sig::VectorOf< double > pwmDutycycle
Definition: jointData.h:46
yarp::sig::VectorOf< double > torque
Definition: jointData.h:44
yarp::sig::VectorOf< double > jointPosition
Definition: jointData.h:32
yarp::sig::VectorOf< double > jointVelocity
Definition: jointData.h:34
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:73
void fromString(const std::string &text)
Initializes bottle from a string.
Definition: Bottle.cpp:207
void append(const Bottle &alt)
Append the content of the given bottle to the current list.
Definition: Bottle.cpp:383
size_type size() const
Gets the number of elements in the bottle.
Definition: Bottle.cpp:254
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition: Bottle.cpp:249
Bottle & findGroup(const std::string &key) const override
Gets a list corresponding to a given keyword.
Definition: Bottle.cpp:305
bool check(const std::string &key) const override
Check if there exists a property of the given name.
Definition: Bottle.cpp:280
Bottle tail() const
Get all but the first element of a bottle.
Definition: Bottle.cpp:391
bool isNull() const override
Checks if the object is invalid.
Definition: Bottle.cpp:373
std::string toString() const override
Gives a human-readable textual representation of the bottle.
Definition: Bottle.cpp:214
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
Definition: Bottle.cpp:290
void close() override
Stop port activity.
bool setEnvelope(PortWriter &envelope) override
Set an envelope (e.g., a timestamp) to the next message which will be sent.
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
void interrupt() override
Interrupt any current reads or writes attached to the port.
void write(bool forceStrict=false)
Write the current object being returned by BufferedPort::prepare.
T & prepare()
Access the object which will be transmitted by the next call to yarp::os::BufferedPort::write.
The Node class.
Definition: Node.h:27
An abstraction for a periodic thread.
bool isRunning() const
Returns true when the thread is started, false otherwise.
void stop()
Call this to stop the thread, this call blocks until the thread is terminated (and releaseThread() ca...
void attach(Port &port)
Attach this buffer to a particular port.
void write(bool forceStrict=false)
Try to write the last buffer returned by PortWriterBuffer::get.
T & get()
A synonym of PortWriterBuffer::prepare.
void attach(Port &port)
Set the Port to which objects will be written.
void setReader(PortReader &reader) override
Set an external reader for port data.
Definition: Port.cpp:505
bool removeCallbackLock() override
Remove a lock on callbacks added with setCallbackLock()
Definition: Port.cpp:694
void interrupt() override
Interrupt any current reads or writes attached to the port.
Definition: Port.cpp:377
bool setEnvelope(PortWriter &envelope) override
Set an envelope (e.g., a timestamp) to the next message which will be sent.
Definition: Port.cpp:541
void close() override
Stop port activity.
Definition: Port.cpp:357
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
Definition: Port.cpp:82
A class for storing options and configuration information.
Definition: Property.h:37
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
Definition: Property.cpp:1034
std::string toString() const override
Return a standard text representation of the content of the object.
Definition: Property.cpp:1052
void fromString(const std::string &txt, bool wipe=true)
Interprets a string as a list of properties.
Definition: Property.cpp:1046
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
Definition: Property.cpp:998
bool check(const std::string &key) const override
Check if there exists a property of the given name.
Definition: Property.cpp:1024
Bottle & findGroup(const std::string &key) const override
Gets a list corresponding to a given keyword.
Definition: Property.cpp:1125
void unput(const std::string &key)
Remove the association from the given key to a value, if present.
Definition: Property.cpp:1029
bool topic(const std::string &name)
Set topic to publish to.
Definition: Publisher.h:67
void write(bool forceStrict=false)
Write the current object being returned by Publisher::prepare.
Definition: Publisher.h:152
A base class for nested structures that can be searched.
Definition: Searchable.h:69
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
virtual std::string toString() const =0
Return a standard text representation of the content of the object.
virtual Bottle & findGroup(const std::string &key) const =0
Gets a list corresponding to a given keyword.
An abstraction for a time stamp and/or sequence number.
Definition: Stamp.h:25
void update()
Set the timestamp to the current time, and increment the sequence number (wrapping to 0 if the sequen...
Definition: Stamp.cpp:113
double getTime() const
Get the time stamp.
Definition: Stamp.cpp:37
A single value (typically within a Bottle).
Definition: Value.h:47
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition: Value.cpp:207
virtual Bottle * asList() const
Get list value.
Definition: Value.cpp:243
std::string toString() const override
Return a standard text representation of the content of the object.
Definition: Value.cpp:359
virtual bool isInt32() const
Checks if value is a 32-bit integer.
Definition: Value.cpp:135
virtual std::string asString() const
Get string value.
Definition: Value.cpp:237
std::vector< std::string > name
Definition: JointState.h:59
std::vector< yarp::conf::float64_t > position
Definition: JointState.h:60
std::vector< yarp::conf::float64_t > velocity
Definition: JointState.h:61
std::vector< yarp::conf::float64_t > effort
Definition: JointState.h:62
yarp::rosmsg::std_msgs::Header header
Definition: JointState.h:58
yarp::rosmsg::TickTime stamp
Definition: Header.h:48
void resize(size_t size) override
Resize the vector.
Definition: Vector.h:254
iterator begin() noexcept
Returns an iterator to the beginning of the VectorOf.
Definition: Vector.h:483
T * data()
Return a pointer to the first element of the vector.
Definition: Vector.h:239
iterator end() noexcept
Returns an iterator to the end of the VectorOf.
Definition: Vector.h:490
#define yCInfo(component,...)
Definition: LogComponent.h:135
#define yCError(component,...)
Definition: LogComponent.h:157
#define yCTrace(component,...)
Definition: LogComponent.h:88
#define yCWarning(component,...)
Definition: LogComponent.h:146
#define yCDebug(component,...)
Definition: LogComponent.h:112
An interface for the device drivers.
PidControlTypeEnum
Definition: PidEnums.h:21
@ VOCAB_JOINTTYPE_REVOLUTE
Definition: IAxisInfo.h:30
An interface to the operating system, including Port based communication.
Signal processing.
Definition: Image.h:25
The main, catch-all namespace for YARP.
Definition: environment.h:18
@ ROS_only
Definition: yarpRosHelper.h:23
@ ROS_config_error
Definition: yarpRosHelper.h:20
@ ROS_enabled
Definition: yarpRosHelper.h:22
@ ROS_disabled
Definition: yarpRosHelper.h:21
double convertDegreesToRadians(double degrees)
convert degrees to radiants for ROS messages
Definition: yarpRosHelper.h:30