YARP
Yet Another Robot Platform
ControlBoardWrapperPidControl.cpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
7 
9 
10 using yarp::dev::Pid;
12 
13 
14 bool ControlBoardWrapperPidControl::setPid(const PidControlTypeEnum& pidtype, int j, const Pid& p)
15 {
16  size_t off;
17  try {
18  off = device.lut.at(j).offset;
19  } catch (...) {
21  "Joint number %d out of bound [0-%zu] for part %s",
22  j,
24  partName.c_str());
25  return false;
26  }
27  size_t subIndex = device.lut[j].deviceEntry;
28 
29  SubDevice* s = device.getSubdevice(subIndex);
30  if (!s) {
31  return false;
32  }
33 
34  if (s->pid) {
35  return s->pid->setPid(pidtype, static_cast<int>(off + s->base), p);
36  }
37  return false;
38 }
39 
40 
42 {
43  bool ret = true;
44 
45  for (size_t l = 0; l < controlledJoints; l++) {
46  int off = device.lut[l].offset;
47  size_t subIndex = device.lut[l].deviceEntry;
48 
49  SubDevice* p = device.getSubdevice(subIndex);
50  if (!p) {
51  return false;
52  }
53 
54  if (p->pid) {
55  ret = ret && p->pid->setPid(pidtype, static_cast<int>(off + p->base), ps[l]);
56  } else {
57  ret = false;
58  }
59  }
60  return ret;
61 }
62 
63 
65 {
66  size_t off;
67  try {
68  off = device.lut.at(j).offset;
69  } catch (...) {
71  "Joint number %d out of bound [0-%zu] for part %s",
72  j,
74  partName.c_str());
75  return false;
76  }
77  size_t subIndex = device.lut[j].deviceEntry;
78 
79  SubDevice* p = device.getSubdevice(subIndex);
80  if (!p) {
81  return false;
82  }
83 
84  if (p->pid) {
85  return p->pid->setPidReference(pidtype, static_cast<int>(off + p->base), ref);
86  }
87  return false;
88 }
89 
90 
92 {
93  bool ret = true;
94 
95  for (size_t l = 0; l < controlledJoints; l++) {
96  int off = device.lut[l].offset;
97  size_t subIndex = device.lut[l].deviceEntry;
98 
99  SubDevice* p = device.getSubdevice(subIndex);
100  if (!p) {
101  return false;
102  }
103 
104  if (p->pid) {
105  ret = ret && p->pid->setPidReference(pidtype, static_cast<int>(off + p->base), refs[l]);
106  } else {
107  ret = false;
108  }
109  }
110  return ret;
111 }
112 
113 
115 {
116  size_t off;
117  try {
118  off = device.lut.at(j).offset;
119  } catch (...) {
120  yCError(CONTROLBOARD, "Joint number %d out of bound [0-%zu] for part %s", j, controlledJoints, partName.c_str());
121  return false;
122  }
123  size_t subIndex = device.lut[j].deviceEntry;
124 
125  SubDevice* p = device.getSubdevice(subIndex);
126  if (!p) {
127  return false;
128  }
129 
130  if (p->pid) {
131  return p->pid->setPidErrorLimit(pidtype, static_cast<int>(off + p->base), limit);
132  }
133  return false;
134 }
135 
136 
138 {
139  bool ret = true;
140 
141  for (size_t l = 0; l < controlledJoints; l++) {
142  int off = device.lut[l].offset;
143  size_t subIndex = device.lut[l].deviceEntry;
144 
145  SubDevice* p = device.getSubdevice(subIndex);
146  if (!p) {
147  return false;
148  }
149 
150  if (p->pid) {
151  ret = ret && p->pid->setPidErrorLimit(pidtype, static_cast<int>(off + p->base), limits[l]);
152  } else {
153  ret = false;
154  }
155  }
156  return ret;
157 }
158 
159 
160 bool ControlBoardWrapperPidControl::getPidError(const PidControlTypeEnum& pidtype, int j, double* err)
161 {
162  size_t off;
163  try {
164  off = device.lut.at(j).offset;
165  } catch (...) {
166  yCError(CONTROLBOARD, "Joint number %d out of bound [0-%zu] for part %s", j, controlledJoints, partName.c_str());
167  return false;
168  }
169  size_t subIndex = device.lut[j].deviceEntry;
170 
171  SubDevice* p = device.getSubdevice(subIndex);
172  if (!p) {
173  return false;
174  }
175 
176  if (p->pid) {
177  return p->pid->getPidError(pidtype, static_cast<int>(off + p->base), err);
178  }
179  *err = 0.0;
180  return false;
181 }
182 
183 
185 {
186  auto* errors = new double[device.maxNumOfJointsInDevices];
187 
188  bool ret = true;
189  for (size_t d = 0; d < device.subdevices.size(); d++) {
190  SubDevice* p = device.getSubdevice(d);
191  if (!p) {
192  ret = false;
193  break;
194  }
195  if ((p->pid) && (ret = p->pid->getPidErrors(pidtype, errors))) {
196  for (size_t juser = p->wbase, jdevice = p->base; juser <= p->wtop; juser++, jdevice++) {
197  errs[juser] = errors[jdevice];
198  }
199  } else {
200  printError("getPidErrors", p->id, ret);
201  ret = false;
202  break;
203  }
204  }
205 
206  delete[] errors;
207  return ret;
208 }
209 
210 
211 bool ControlBoardWrapperPidControl::getPidOutput(const PidControlTypeEnum& pidtype, int j, double* out)
212 {
213  size_t off;
214  try {
215  off = device.lut.at(j).offset;
216  } catch (...) {
217  yCError(CONTROLBOARD, "Joint number %d out of bound [0-%zu] for part %s", j, controlledJoints, partName.c_str());
218  return false;
219  }
220  size_t subIndex = device.lut[j].deviceEntry;
221 
222  SubDevice* p = device.getSubdevice(subIndex);
223  if (!p) {
224  return false;
225  }
226 
227  if (p->pid) {
228  return p->pid->getPidOutput(pidtype, static_cast<int>(off + p->base), out);
229  }
230  *out = 0.0;
231  return false;
232 }
233 
234 
236 {
237  auto* outputs = new double[device.maxNumOfJointsInDevices];
238  bool ret = true;
239  for (size_t d = 0; d < device.subdevices.size(); d++) {
240  SubDevice* p = device.getSubdevice(d);
241  if (!p) {
242  ret = false;
243  break;
244  }
245 
246  if ((p->pid) && (ret = p->pid->getPidOutputs(pidtype, outputs))) {
247  for (size_t juser = p->wbase, jdevice = p->base; juser <= p->wtop; juser++, jdevice++) {
248  outs[juser] = outputs[jdevice];
249  }
250  } else {
251  printError("getPidOutouts", p->id, ret);
252  ret = false;
253  break;
254  }
255  }
256 
257  delete[] outputs;
258  return ret;
259 }
260 
261 
263 {
264  size_t off;
265  try {
266  off = device.lut.at(j).offset;
267  } catch (...) {
268  yCError(CONTROLBOARD, "Joint number %d out of bound [0-%zu] for part %s", j, controlledJoints, partName.c_str());
269  return false;
270  }
271  size_t subIndex = device.lut[j].deviceEntry;
272 
273  SubDevice* p = device.getSubdevice(subIndex);
274  if (!p) {
275  return false;
276  }
277 
278  if (p->pid) {
279  return p->pid->setPidOffset(pidtype, static_cast<int>(off + p->base), v);
280  }
281  return false;
282 }
283 
284 
286 {
287  //#warning "check for max number of joints!?!?!"
288  size_t off;
289  try {
290  off = device.lut.at(j).offset;
291  } catch (...) {
292  yCError(CONTROLBOARD, "Joint number %d out of bound [0-%zu] for part %s", j, controlledJoints, partName.c_str());
293  return false;
294  }
295  size_t subIndex = device.lut[j].deviceEntry;
296 
297  SubDevice* s = device.getSubdevice(subIndex);
298  if (!s) {
299  return false;
300  }
301 
302  if (s->pid) {
303  return s->pid->getPid(pidtype, static_cast<int>(off + s->base), p);
304  }
305  return false;
306 }
307 
308 
310 {
311  Pid* pids_device = new Pid[device.maxNumOfJointsInDevices];
312  bool ret = true;
313  for (size_t d = 0; d < device.subdevices.size(); d++) {
314  SubDevice* p = device.getSubdevice(d);
315  if (!p) {
316  ret = false;
317  break;
318  }
319 
320  if ((p->pid) && (ret = p->pid->getPids(pidtype, pids_device))) {
321  for (size_t juser = p->wbase, jdevice = p->base; juser <= p->wtop; juser++, jdevice++) {
322  pids[juser] = pids_device[jdevice];
323  }
324  } else {
325  printError("getPids", p->id, ret);
326  ret = false;
327  break;
328  }
329  }
330 
331  delete[] pids_device;
332  return ret;
333 }
334 
335 
337 {
338  size_t off;
339  try {
340  off = device.lut.at(j).offset;
341  } catch (...) {
342  yCError(CONTROLBOARD, "Joint number %d out of bound [0-%zu] for part %s", j, controlledJoints, partName.c_str());
343  return false;
344  }
345  size_t subIndex = device.lut[j].deviceEntry;
346 
347  SubDevice* p = device.getSubdevice(subIndex);
348  if (!p) {
349  return false;
350  }
351  if (p->pid) {
352  return p->pid->getPidReference(pidtype, static_cast<int>(off + p->base), ref);
353  }
354  return false;
355 }
356 
357 
359 {
360  auto* references = new double[device.maxNumOfJointsInDevices];
361  bool ret = true;
362  for (size_t d = 0; d < device.subdevices.size(); d++) {
363  SubDevice* p = device.getSubdevice(d);
364  if (!p) {
365  ret = false;
366  break;
367  }
368 
369  if ((p->pid) && (ret = p->pid->getPidReferences(pidtype, references))) {
370  for (size_t juser = p->wbase, jdevice = p->base; juser <= p->wtop; juser++, jdevice++) {
371  refs[juser] = references[jdevice];
372  }
373  } else {
374  printError("getPidReferences", p->id, ret);
375  ret = false;
376  break;
377  }
378  }
379 
380  delete[] references;
381  return ret;
382 }
383 
384 
385 bool ControlBoardWrapperPidControl::getPidErrorLimit(const PidControlTypeEnum& pidtype, int j, double* limit)
386 {
387  size_t off;
388  try {
389  off = device.lut.at(j).offset;
390  } catch (...) {
391  yCError(CONTROLBOARD, "Joint number %d out of bound [0-%zu] for part %s", j, controlledJoints, partName.c_str());
392  return false;
393  }
394  size_t subIndex = device.lut[j].deviceEntry;
395 
396  SubDevice* p = device.getSubdevice(subIndex);
397  if (!p) {
398  return false;
399  }
400 
401  if (p->pid) {
402  return p->pid->getPidErrorLimit(pidtype, static_cast<int>(off + p->base), limit);
403  }
404  return false;
405 }
406 
407 
409 {
410  auto* lims = new double[device.maxNumOfJointsInDevices];
411  bool ret = true;
412  for (size_t d = 0; d < device.subdevices.size(); d++) {
413  SubDevice* p = device.getSubdevice(d);
414  if (!p) {
415  ret = false;
416  break;
417  }
418 
419  if ((p->pid) && (ret = p->pid->getPidErrorLimits(pidtype, lims))) {
420  for (size_t juser = p->wbase, jdevice = p->base; juser <= p->wtop; juser++, jdevice++) {
421  limits[juser] = lims[jdevice];
422  }
423  } else {
424  printError("getPidErrorLimits", p->id, ret);
425  ret = false;
426  break;
427  }
428  }
429 
430  delete[] lims;
431  return ret;
432 }
433 
434 
436 {
437  size_t off;
438  try {
439  off = device.lut.at(j).offset;
440  } catch (...) {
441  yCError(CONTROLBOARD, "Joint number %d out of bound [0-%zu] for part %s", j, controlledJoints, partName.c_str());
442  return false;
443  }
444  size_t subIndex = device.lut[j].deviceEntry;
445 
446  SubDevice* p = device.getSubdevice(subIndex);
447  if (!p) {
448  return false;
449  }
450 
451  if (p->pid) {
452  return p->pid->resetPid(pidtype, static_cast<int>(off + p->base));
453  }
454  return false;
455 }
456 
457 
459 {
460  size_t off;
461  try {
462  off = device.lut.at(j).offset;
463  } catch (...) {
464  yCError(CONTROLBOARD, "Joint number %d out of bound [0-%zu] for part %s", j, controlledJoints, partName.c_str());
465  return false;
466  }
467  size_t subIndex = device.lut[j].deviceEntry;
468 
469  SubDevice* p = device.getSubdevice(subIndex);
470  if (!p) {
471  return false;
472  }
473 
474  if (p->pid) {
475  return p->pid->disablePid(pidtype, static_cast<int>(off + p->base));
476  }
477  return false;
478 }
479 
480 
482 {
483  size_t off;
484  try {
485  off = device.lut.at(j).offset;
486  } catch (...) {
487  yCError(CONTROLBOARD, "Joint number %d out of bound [0-%zu] for part %s", j, controlledJoints, partName.c_str());
488  return false;
489  }
490  size_t subIndex = device.lut[j].deviceEntry;
491 
492  SubDevice* p = device.getSubdevice(subIndex);
493  if (!p) {
494  return false;
495  }
496 
497  if (p->pid) {
498  return p->pid->enablePid(pidtype, static_cast<int>(off + p->base));
499  }
500  return false;
501 }
502 
503 
504 bool ControlBoardWrapperPidControl::isPidEnabled(const PidControlTypeEnum& pidtype, int j, bool* enabled)
505 {
506  size_t off;
507  try {
508  off = device.lut.at(j).offset;
509  } catch (...) {
510  yCError(CONTROLBOARD, "Joint number %d out of bound [0-%zu] for part %s", j, controlledJoints, partName.c_str());
511  return false;
512  }
513  size_t subIndex = device.lut[j].deviceEntry;
514 
515  SubDevice* p = device.getSubdevice(subIndex);
516  if (!p) {
517  return false;
518  }
519 
520  if (p->pid) {
521  return p->pid->isPidEnabled(pidtype, static_cast<int>(off + p->base), enabled);
522  }
523 
524  return false;
525 }
const yarp::os::LogComponent & CONTROLBOARD()
bool ret
void printError(const std::string &func_name, const std::string &info, bool result)
bool enablePid(const yarp::dev::PidControlTypeEnum &pidtype, int j) override
Enable the pid computation for a joint.
bool getPids(const yarp::dev::PidControlTypeEnum &pidtype, yarp::dev::Pid *pids) override
Get current pid value for a specific joint.
bool setPidReferences(const yarp::dev::PidControlTypeEnum &pidtype, const double *refs) override
Set the controller reference, multiple axes.
bool getPidError(const yarp::dev::PidControlTypeEnum &pidtype, int j, double *err) override
Get the current error for a joint.
bool setPidErrorLimit(const yarp::dev::PidControlTypeEnum &pidtype, int j, double limit) override
Set the error limit for the controller on a specifi joint.
bool getPidReferences(const yarp::dev::PidControlTypeEnum &pidtype, double *refs) override
Get the current reference of all pid controllers.
bool setPidReference(const yarp::dev::PidControlTypeEnum &pidtype, int j, double ref) override
Set the controller reference for a given axis.
bool isPidEnabled(const yarp::dev::PidControlTypeEnum &pidtype, int j, bool *enabled) override
Get the current status (enabled/disabled) of the pid.
bool getPidOutputs(const yarp::dev::PidControlTypeEnum &pidtype, double *outs) override
Get the output of the controllers (e.g.
bool setPidOffset(const yarp::dev::PidControlTypeEnum &pidtype, int j, double v) override
Set offset value for a given controller.
bool getPidOutput(const yarp::dev::PidControlTypeEnum &pidtype, int j, double *out) override
Get the output of the controller (e.g.
bool setPids(const yarp::dev::PidControlTypeEnum &pidtype, const yarp::dev::Pid *ps) override
Set new pid value on multiple axes.
bool disablePid(const yarp::dev::PidControlTypeEnum &pidtype, int j) override
Disable the pid computation for a joint.
bool setPid(const yarp::dev::PidControlTypeEnum &pidtype, int j, const yarp::dev::Pid &p) override
Set new pid value for a joint axis.
bool setPidErrorLimits(const yarp::dev::PidControlTypeEnum &pidtype, const double *limits) override
Get the error limit for the controller on all joints.
bool getPid(const yarp::dev::PidControlTypeEnum &pidtype, int j, yarp::dev::Pid *p) override
Get current pid value for a specific joint.
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 getPidErrors(const yarp::dev::PidControlTypeEnum &pidtype, double *errs) override
Get the error of all joints.
bool getPidErrorLimits(const yarp::dev::PidControlTypeEnum &pidtype, double *limits) override
Get the error limit for all controllers.
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 getPidErrorLimit(const yarp::dev::PidControlTypeEnum &pidtype, int j, double *limit) override
Get the error limit for the controller on a specific joint.
size_t base
Definition: SubDevice.h:55
std::string id
Definition: SubDevice.h:54
yarp::dev::IPidControl * pid
Definition: SubDevice.h:67
size_t wbase
Definition: SubDevice.h:57
std::vector< DevicesLutEntry > lut
Definition: SubDevice.h:122
SubDevice * getSubdevice(size_t i)
Definition: SubDevice.h:125
size_t maxNumOfJointsInDevices
Definition: SubDevice.h:123
SubDeviceVector subdevices
Definition: SubDevice.h:121
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.
Contains the parameters for a PID.
#define yCError(component,...)
Definition: LogComponent.h:154
PidControlTypeEnum
Definition: PidEnums.h:18