NJointPeriodicTSDMPCompliantController.cpp
Go to the documentation of this file.
2 
4 
6 {
7  NJointControllerRegistration<NJointPeriodicTSDMPCompliantController> registrationControllerNJointPeriodicTSDMPCompliantController("NJointPeriodicTSDMPCompliantController");
8 
9  NJointPeriodicTSDMPCompliantController::NJointPeriodicTSDMPCompliantController(const RobotUnitPtr& robUnit, const armarx::NJointControllerConfigPtr& config, const VirtualRobot::RobotPtr&)
10  {
12  cfg = NJointPeriodicTSDMPCompliantControllerConfigPtr::dynamicCast(config);
13  ARMARX_CHECK_EXPRESSION(!cfg->nodeSetName.empty());
14  VirtualRobot::RobotNodeSetPtr rns = rtGetRobot()->getRobotNodeSet(cfg->nodeSetName);
15 
16  ARMARX_CHECK_EXPRESSION(rns) << cfg->nodeSetName;
17  for (size_t i = 0; i < rns->getSize(); ++i)
18  {
19  std::string jointName = rns->getNode(i)->getName();
20  ControlTargetBase* ct = useControlTarget(jointName, ControlModes::Torque1DoF);
21  const SensorValueBase* sv = useSensorValue(jointName);
22  targets.push_back(ct->asA<ControlTarget1DoFActuatorTorque>());
23 
24  const SensorValue1DoFActuatorVelocity* velocitySensor = sv->asA<SensorValue1DoFActuatorVelocity>();
25  const SensorValue1DoFActuatorPosition* positionSensor = sv->asA<SensorValue1DoFActuatorPosition>();
26 
27  velocitySensors.push_back(velocitySensor);
28  positionSensors.push_back(positionSensor);
29  };
30 
31  tcp = rns->getTCP();
32  // set tcp controller
33  nodeSetName = cfg->nodeSetName;
34  ik.reset(new VirtualRobot::DifferentialIK(rns, rns->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
35 
36  tsvmp::TaskSpaceDMPControllerConfig taskSpaceDMPConfig;
37  taskSpaceDMPConfig.motionTimeDuration = cfg->timeDuration;
38  taskSpaceDMPConfig.DMPKernelSize = cfg->kernelSize;
39  taskSpaceDMPConfig.DMPAmplitude = cfg->dmpAmplitude;
40  taskSpaceDMPConfig.DMPMode = "Linear";
41  taskSpaceDMPConfig.DMPStyle = "Periodic";
42  taskSpaceDMPConfig.phaseStopParas.goDist = cfg->phaseDist0;
43  taskSpaceDMPConfig.phaseStopParas.backDist = cfg->phaseDist1;
44  taskSpaceDMPConfig.phaseStopParas.Kpos = cfg->phaseKpPos;
45  taskSpaceDMPConfig.phaseStopParas.Kori = cfg->phaseKpOri;
46  taskSpaceDMPConfig.phaseStopParas.mm2radi = cfg->posToOriRatio;
47  taskSpaceDMPConfig.phaseStopParas.maxValue = cfg->phaseL;
48  taskSpaceDMPConfig.phaseStopParas.slop = cfg->phaseK;
49  taskSpaceDMPConfig.phaseStopParas.Dpos = 0;
50  taskSpaceDMPConfig.phaseStopParas.Dori = 0;
51 
52 
53 
54  dmpCtrl.reset(new tsvmp::TaskSpaceDMPController("periodicDMP", taskSpaceDMPConfig, false));
55 
57  initData.targetTSVel.resize(6);
58  for (size_t i = 0; i < 6; ++i)
59  {
60  initData.targetTSVel(i) = 0;
61  }
62  reinitTripleBuffer(initData);
63 
64  firstRun = true;
65  dmpRunning = false;
66 
67 
68  ARMARX_CHECK_EQUAL(cfg->Kpos.size(), 3);
69  ARMARX_CHECK_EQUAL(cfg->Dpos.size(), 3);
70  ARMARX_CHECK_EQUAL(cfg->Kori.size(), 3);
71  ARMARX_CHECK_EQUAL(cfg->Dori.size(), 3);
72 
73  kpos << cfg->Kpos[0], cfg->Kpos[1], cfg->Kpos[2];
74  dpos << cfg->Dpos[0], cfg->Dpos[1], cfg->Dpos[2];
75  kori << cfg->Kori[0], cfg->Kori[1], cfg->Kori[2];
76  dori << cfg->Dori[0], cfg->Dori[1], cfg->Dori[2];
77 
78  kpf = cfg->Kpf;
79  knull = cfg->Knull;
80  dnull = cfg->Dnull;
81 
82 
83 
84  nullSpaceJointsVec.resize(cfg->desiredNullSpaceJointValues.size());
85  for (size_t i = 0; i < cfg->desiredNullSpaceJointValues.size(); ++i)
86  {
87  nullSpaceJointsVec(i) = cfg->desiredNullSpaceJointValues.at(i);
88  }
89 
90 
91  const SensorValueBase* svlf = robUnit->getSensorDevice(cfg->forceSensorName)->getSensorValue();
92  forceSensor = svlf->asA<SensorValueForceTorque>();
93 
94  forceOffset.setZero();
95  filteredForce.setZero();
96  filteredForceInRoot.setZero();
97 
98 
99  UserToRTData initUserData;
100  initUserData.targetForce = 0;
101  user2rtData.reinitAllBuffers(initUserData);
102 
103  oriToolDir << 0, 0, 1;
104 
105  qvel_filtered.setZero(targets.size());
106 
107  ARMARX_CHECK_EQUAL(cfg->ws_x.size(), 2);
108  ARMARX_CHECK_EQUAL(cfg->ws_y.size(), 2);
109  ARMARX_CHECK_EQUAL(cfg->ws_z.size(), 2);
110 
111  // only for ARMAR-6 (safe-guard)
112  if (!cfg->ignoreWSLimitChecks)
113  {
114  ARMARX_CHECK_LESS(cfg->ws_x[0], cfg->ws_x[1]);
115  ARMARX_CHECK_LESS(cfg->ws_x[0], 1000);
116  ARMARX_CHECK_LESS(-200, cfg->ws_x[1]);
117 
118  ARMARX_CHECK_LESS(cfg->ws_y[0], cfg->ws_y[1]);
119  ARMARX_CHECK_LESS(cfg->ws_y[0], 1200);
120  ARMARX_CHECK_LESS(0, cfg->ws_y[1]);
121 
122  ARMARX_CHECK_LESS(cfg->ws_z[0], cfg->ws_z[1]);
123  ARMARX_CHECK_LESS(cfg->ws_z[0], 1800);
124  ARMARX_CHECK_LESS(300, cfg->ws_z[1]);
125  }
126 
127  adaptK = kpos;
128  lastDiff = 0;
129  changeTimer = 0;
130 
131 
132  isManipulability = cfg->isManipulability;
133 
134 
135  ARMARX_CHECK_EQUAL(cfg->maniWeight.size(), rns->getNodeNames().size());
136  Eigen::VectorXd maniWeightVec;
137  maniWeightVec.setOnes(rns->getNodeNames().size());
138  for (size_t i = 0; i < cfg->maniWeight.size(); ++i)
139  {
140  maniWeightVec(i) = cfg->maniWeight[i];
141  }
142 
143  Eigen::MatrixXd maniWeightMat = maniWeightVec.asDiagonal();
144  VirtualRobot::SingleRobotNodeSetManipulabilityPtr manipulability(
145  new VirtualRobot::SingleRobotNodeSetManipulability(rns, rns->getTCP(),
147  VirtualRobot::AbstractManipulability::Type::Velocity,
148  rns->getRobot()->getRootNode(), maniWeightMat));
149  manipulabilityTracker.reset(new VirtualRobot::SingleChainManipulabilityTracking(manipulability));
150 
151  ARMARX_CHECK_EQUAL(cfg->positionManipulability.size(), 9);
152  targetManipulability.setZero(3, 3);
153  targetManipulability << cfg->positionManipulability[0], cfg->positionManipulability[1], cfg->positionManipulability[2],
154  cfg->positionManipulability[3], cfg->positionManipulability[4], cfg->positionManipulability[5],
155  cfg->positionManipulability[6], cfg->positionManipulability[7], cfg->positionManipulability[8];
156 
157 
158  Eigen::VectorXd kmaniVec;
159  kmaniVec.setZero(cfg->kmani.size());
160  for (size_t i = 0; i < cfg->kmani.size(); ++i)
161  {
162  kmaniVec[i] = cfg->kmani[i];
163  }
164 
165  kmani = kmaniVec.asDiagonal();
166 
167  }
168 
170  {
171  ARMARX_INFO << "init ...";
172 
173 
174  RTToControllerData initSensorData;
175  initSensorData.deltaT = 0;
176  initSensorData.currentTime = 0;
177  initSensorData.currentPose = tcp->getPoseInRootFrame();
178  initSensorData.currentTwist.setZero();
179  initSensorData.isPhaseStop = false;
180  rt2CtrlData.reinitAllBuffers(initSensorData);
181 
182  RTToUserData initInterfaceData;
183  initInterfaceData.currentTcpPose = tcp->getPoseInRootFrame();
184  initInterfaceData.waitTimeForCalibration = 0;
185  rt2UserData.reinitAllBuffers(initInterfaceData);
186 
187 
188  ARMARX_IMPORTANT << "read force sensor ...";
189 
190  forceOffset = forceSensor->force;
191 
192  ARMARX_IMPORTANT << "force offset: " << forceOffset;
193 
194  started = false;
195 
196  runTask("NJointPeriodicTSDMPCompliantController", [&]
197  {
198  CycleUtil c(1);
199  getObjectScheduler()->waitForObjectStateMinimum(eManagedIceObjectStarted);
200  while (getState() == eManagedIceObjectStarted)
201  {
202  if (isControllerActive())
203  {
204  controllerRun();
205  }
206  c.waitForCycleDuration();
207  }
208  });
209 
210  ARMARX_IMPORTANT << "started controller ";
211 
212  }
213 
214  std::string NJointPeriodicTSDMPCompliantController::getClassName(const Ice::Current&) const
215  {
216  return "NJointPeriodicTSDMPCompliantController";
217  }
218 
220  {
221  if (!started)
222  {
223  return;
224  }
225 
226  if (!dmpCtrl)
227  {
228  return;
229  }
230 
231  Eigen::VectorXf targetVels(6);
232  bool isPhaseStop = rt2CtrlData.getUpToDateReadBuffer().isPhaseStop;
233  if (isPhaseStop)
234  {
235  targetVels.setZero();
236  }
237  else
238  {
239 
240  double deltaT = rt2CtrlData.getUpToDateReadBuffer().deltaT;
241  Eigen::Matrix4f currentPose = rt2CtrlData.getUpToDateReadBuffer().currentPose;
242  Eigen::VectorXf currentTwist = rt2CtrlData.getUpToDateReadBuffer().currentTwist;
243 
244  LockGuardType guard {controllerMutex};
245  dmpCtrl->flow(deltaT, currentPose, currentTwist);
246 
247  targetVels = dmpCtrl->getTargetVelocity();
248 
249  debugOutputData.getWriteBuffer().latestTargetVelocities["x_vel"] = targetVels(0);
250  debugOutputData.getWriteBuffer().latestTargetVelocities["y_vel"] = targetVels(1);
251  debugOutputData.getWriteBuffer().latestTargetVelocities["z_vel"] = targetVels(2);
252  debugOutputData.getWriteBuffer().latestTargetVelocities["roll_vel"] = targetVels(3);
253  debugOutputData.getWriteBuffer().latestTargetVelocities["pitch_vel"] = targetVels(4);
254  debugOutputData.getWriteBuffer().latestTargetVelocities["yaw_vel"] = targetVels(5);
255  debugOutputData.getWriteBuffer().currentPose["currentPose_x"] = currentPose(0, 3);
256  debugOutputData.getWriteBuffer().currentPose["currentPose_y"] = currentPose(1, 3);
257  debugOutputData.getWriteBuffer().currentPose["currentPose_z"] = currentPose(2, 3);
258  VirtualRobot::MathTools::Quaternion currentQ = VirtualRobot::MathTools::eigen4f2quat(currentPose);
259  debugOutputData.getWriteBuffer().currentPose["currentPose_qw"] = currentQ.w;
260  debugOutputData.getWriteBuffer().currentPose["currentPose_qx"] = currentQ.x;
261  debugOutputData.getWriteBuffer().currentPose["currentPose_qy"] = currentQ.y;
262  debugOutputData.getWriteBuffer().currentPose["currentPose_qz"] = currentQ.z;
263  debugOutputData.getWriteBuffer().currentCanVal = dmpCtrl->debugData.canVal;
264  debugOutputData.getWriteBuffer().mpcFactor = dmpCtrl->debugData.mpcFactor;
265  debugOutputData.getWriteBuffer().error = dmpCtrl->debugData.poseError;
266  debugOutputData.getWriteBuffer().posError = dmpCtrl->debugData.posiError;
267  debugOutputData.getWriteBuffer().oriError = dmpCtrl->debugData.oriError;
268  debugOutputData.getWriteBuffer().deltaT = deltaT;
269  debugOutputData.commitWrite();
270  }
271 
272  getWriterControlStruct().targetTSVel = targetVels;
274 
275  dmpRunning = true;
276  }
277 
278 
279  void NJointPeriodicTSDMPCompliantController::rtRun(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration)
280  {
281  double deltaT = timeSinceLastIteration.toSecondsDouble();
282 
283  Eigen::Matrix4f currentPose = tcp->getPoseInRootFrame();
284  rt2UserData.getWriteBuffer().currentTcpPose = currentPose;
285  rt2UserData.getWriteBuffer().waitTimeForCalibration += deltaT;
286  rt2UserData.commitWrite();
287 
288 
289  Eigen::MatrixXf jacobi = ik->getJacobianMatrix(tcp, VirtualRobot::IKSolver::CartesianSelection::All);
290 
291  Eigen::VectorXf qpos(positionSensors.size());
292  Eigen::VectorXf qvel(velocitySensors.size());
293  for (size_t i = 0; i < positionSensors.size(); ++i)
294  {
295  qpos(i) = positionSensors[i]->position;
296  qvel(i) = velocitySensors[i]->velocity;
297  }
298 
299  qvel_filtered = (1 - cfg->velFilter) * qvel_filtered + cfg->velFilter * qvel;
300  Eigen::VectorXf currentTwist = jacobi * qvel_filtered;
301 
302  Eigen::VectorXf targetVel(6);
303  targetVel.setZero();
304  if (firstRun || !dmpRunning)
305  {
306  lastPosition = currentPose.block<2, 1>(0, 3);
307  targetPose = currentPose;
308  firstRun = false;
309  filteredForce.setZero();
310 
311  origHandOri = currentPose.block<3, 3>(0, 0);
312  toolTransform = origHandOri.transpose();
313  // force calibration
314  if (!dmpRunning)
315  {
316  forceOffset = (1 - cfg->forceFilter) * forceOffset + cfg->forceFilter * forceSensor->force;
317  }
318 
319  targetVel.setZero();
320  }
321  else
322  {
323  // communicate with DMP controller
325  targetVel = rtGetControlStruct().targetTSVel;
326  targetVel(2) = 0;
327 
328  // force detection
329  filteredForce = (1 - cfg->forceFilter) * filteredForce + cfg->forceFilter * (forceSensor->force - forceOffset);
330 
331  for (size_t i = 0; i < 3; ++i)
332  {
333  if (fabs(filteredForce(i)) > cfg->forceDeadZone)
334  {
335  filteredForce(i) -= (filteredForce(i) / fabs(filteredForce(i))) * cfg->forceDeadZone;
336  }
337  else
338  {
339  filteredForce(i) = 0;
340  }
341  }
342  Eigen::Matrix4f forceFrameInRoot = rtGetRobot()->getSensor(cfg->forceSensorName)->getRobotNode()->getPoseInRootFrame();
343 
344  filteredForceInRoot = forceFrameInRoot.block<3, 3>(0, 0) * filteredForce;
345  float targetForce = user2rtData.getUpToDateReadBuffer().targetForce;
346 
347  // Eigen::Matrix3f currentHandOri = currentPose.block<3, 3>(0, 0);
348  // Eigen::Matrix3f currentToolOri = toolTransform * currentHandOri;
349  float desiredZVel = kpf * (targetForce - filteredForceInRoot(2));
350  targetVel(2) -= desiredZVel;
351  // targetVel.block<3, 1>(0, 0) = currentToolOri * targetVel.block<3, 1>(0, 0);
352 
353 
354  // Eigen::Vector3f currentToolDir = currentToolOri * oriToolDir;
355 
356  for (int i = 3; i < 6; ++i)
357  {
358  targetVel(i) = 0;
359  }
360 
361  // rotation changes
362 
363  // if (filteredForceInRoot.norm() > fabs(cfg->minimumReactForce))
364  // {
365  // Eigen::Vector3f desiredToolDir = filteredForceInRoot / filteredForceInRoot.norm();
366  // currentToolDir = currentToolDir / currentToolDir.norm();
367  // Eigen::Vector3f axis = currentToolDir.cross(desiredToolDir);
368  // float angle = acosf(currentToolDir.dot(desiredToolDir));
369 
370  // if (fabs(angle) < M_PI / 2)
371  // {
372  // Eigen::AngleAxisf desiredToolRot(angle, axis);
373  // Eigen::Matrix3f desiredRotMat = desiredToolRot * Eigen::Matrix3f::Identity();
374 
375  // targetPose.block<3, 3>(0, 0) = desiredRotMat * currentHandOri;
376 
377  // Eigen::Vector3f desiredRPY = VirtualRobot::MathTools::eigen3f2rpy(desiredRotMat);
378  // Eigen::Vector3f checkedToolDir = desiredRotMat * currentToolDir;
379  // ARMARX_IMPORTANT << "axis: " << axis;
380  // ARMARX_IMPORTANT << "angle: " << angle * 180 / 3.1415;
381  // ARMARX_IMPORTANT << "desiredRotMat: " << desiredRotMat;
382 
383  // ARMARX_IMPORTANT << "desiredToolDir: " << desiredToolDir;
384  // ARMARX_IMPORTANT << "currentToolDir: " << currentToolDir;
385  // ARMARX_IMPORTANT << "checkedToolDir: " << checkedToolDir;
386  // }
387 
388  // }
389 
390 
391  // integrate for targetPose
392 
393 
394 
395 
396 
397  }
398 
399  bool isPhaseStop = false;
400 
401  float diff = (targetPose.block<2, 1>(0, 3) - currentPose.block<2, 1>(0, 3)).norm();
402  if (diff > cfg->phaseDist0)
403  {
404  isPhaseStop = true;
405  }
406 
407  float dTf = (float)deltaT;
408 
409 
410  if (filteredForceInRoot.block<2, 1>(0, 0).norm() > cfg->dragForceDeadZone)
411  {
412  Eigen::Vector2f dragForce = filteredForceInRoot.block<2, 1>(0, 0) - cfg->dragForceDeadZone * filteredForceInRoot.block<2, 1>(0, 0) / filteredForceInRoot.block<2, 1>(0, 0).norm();
413  adaptK(0) = fmax(adaptK(0) - dTf * cfg->adaptForceCoeff * dragForce.norm(), 0);
414  adaptK(1) = fmax(adaptK(1) - dTf * cfg->adaptForceCoeff * dragForce.norm(), 0);
415  lastDiff = diff;
416  }
417  else
418  {
419  adaptK(0) = fmin(adaptK(0) + fabs(dTf * cfg->adaptCoeff), kpos(0));
420  adaptK(1) = fmin(adaptK(1) + fabs(dTf * cfg->adaptCoeff), kpos(1));
421  }
422  adaptK(2) = kpos(2);
423 
424  // adaptive control with distance
425 
426 
427 
428 
429  targetPose.block<3, 1>(0, 3) = targetPose.block<3, 1>(0, 3) + dTf * targetVel.block<3, 1>(0, 0);
430 
431  if (isPhaseStop)
432  {
433  Eigen::Vector2f currentXY = currentPose.block<2, 1>(0, 3);
434  if ((lastPosition - currentXY).norm() < cfg->changePositionTolerance)
435  {
436  changeTimer += deltaT;
437  }
438  else
439  {
440  lastPosition = currentPose.block<2, 1>(0, 3);
441  changeTimer = 0;
442  }
443 
444  if (changeTimer > cfg->changeTimerThreshold)
445  {
446  targetPose(0, 3) = currentPose(0, 3);
447  targetPose(1, 3) = currentPose(1, 3);
448  isPhaseStop = false;
449  changeTimer = 0;
450  }
451  }
452  else
453  {
454  changeTimer = 0;
455  }
456 
457 
458  targetPose(0, 3) = targetPose(0, 3) > cfg->ws_x[0] ? targetPose(0, 3) : cfg->ws_x[0];
459  targetPose(0, 3) = targetPose(0, 3) < cfg->ws_x[1] ? targetPose(0, 3) : cfg->ws_x[1];
460 
461  targetPose(1, 3) = targetPose(1, 3) > cfg->ws_y[0] ? targetPose(1, 3) : cfg->ws_y[0];
462  targetPose(1, 3) = targetPose(1, 3) < cfg->ws_y[1] ? targetPose(1, 3) : cfg->ws_y[1];
463 
464  targetPose(2, 3) = targetPose(2, 3) > cfg->ws_z[0] ? targetPose(2, 3) : cfg->ws_z[0];
465  targetPose(2, 3) = targetPose(2, 3) < cfg->ws_z[1] ? targetPose(2, 3) : cfg->ws_z[1];
466 
467 
468 
469 
470  debugRT.getWriteBuffer().targetPose = targetPose;
471  debugRT.getWriteBuffer().currentPose = currentPose;
472  debugRT.getWriteBuffer().filteredForce = filteredForceInRoot;
473  debugRT.getWriteBuffer().targetVel = targetVel;
474  debugRT.getWriteBuffer().adaptK = adaptK;
475  debugRT.getWriteBuffer().isPhaseStop = isPhaseStop;
476  debugRT.getWriteBuffer().currentTwist = currentTwist;
477 
478  rt2CtrlData.getWriteBuffer().currentPose = currentPose;
479  rt2CtrlData.getWriteBuffer().currentTwist = currentTwist;
480  rt2CtrlData.getWriteBuffer().deltaT = deltaT;
481  rt2CtrlData.getWriteBuffer().currentTime += deltaT;
482  rt2CtrlData.getWriteBuffer().isPhaseStop = isPhaseStop;
483  rt2CtrlData.commitWrite();
484 
485  // Eigen::Matrix3f rotVel = VirtualRobot::MathTools::rpy2eigen3f(targetVel(3) * dTf, targetVel(4) * dTf, targetVel(5) * dTf);
486  // targetPose.block<3, 3>(0, 0) = rotVel * targetPose.block<3, 3>(0, 0);
487 
488  // inverse dynamic controller
489 
490  for (size_t ki = 0; ki < 3; ++ki)
491  {
492  jacobi.row(ki) = 0.001 * jacobi.row(ki); // convert mm to m
493 
494  }
495 
496 
497 
498 
499  Eigen::Vector6f jointControlWrench;
500  {
501  Eigen::Vector3f targetTCPLinearVelocity;
502  targetTCPLinearVelocity << 0.001 * targetVel(0), 0.001 * targetVel(1), 0.001 * targetVel(2);
503  Eigen::Vector3f currentTCPLinearVelocity;
504  currentTCPLinearVelocity << 0.001 * currentTwist(0), 0.001 * currentTwist(1), 0.001 * currentTwist(2);
505  Eigen::Vector3f currentTCPPosition = currentPose.block<3, 1>(0, 3);
506  Eigen::Vector3f desiredPosition = targetPose.block<3, 1>(0, 3);
507 
508  Eigen::Vector3f linearVel = adaptK.cwiseProduct(desiredPosition - currentTCPPosition);
509 
510  // if (isPhaseStop)
511  // {
512  // linearVel = ((float)cfg->phaseKpPos) * (desiredPosition - currentTCPPosition);
513  // for (size_t i = 0; i < 3; ++i)
514  // {
515  // linearVel(i) = fmin(cfg->maxLinearVel, linearVel(i));
516  // }
517  // }
518  // else
519  // {
520  // linearVel = kpos.cwiseProduct(desiredPosition - currentTCPPosition);
521  // }
522  Eigen::Vector3f tcpDesiredForce = 0.001 * linearVel + dpos.cwiseProduct(- currentTCPLinearVelocity);
523 
524  Eigen::Vector3f currentTCPAngularVelocity;
525  currentTCPAngularVelocity << currentTwist(3), currentTwist(4), currentTwist(5);
526  Eigen::Matrix3f currentRotMat = currentPose.block<3, 3>(0, 0);
527  Eigen::Matrix3f diffMat = targetPose.block<3, 3>(0, 0) * currentRotMat.inverse();
528  Eigen::Vector3f rpy = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
529  Eigen::Vector3f tcpDesiredTorque = kori.cwiseProduct(rpy) + dori.cwiseProduct(- currentTCPAngularVelocity);
530  jointControlWrench << tcpDesiredForce, tcpDesiredTorque;
531  }
532 
533 
534 
535  Eigen::MatrixXf I = Eigen::MatrixXf::Identity(targets.size(), targets.size());
536  Eigen::VectorXf nullspaceTorque;
537 
538  float manidist = 0;
539  if (isManipulability)
540  {
541  nullspaceTorque = manipulabilityTracker->calculateVelocity(targetManipulability, kmani, true);
542  manidist = manipulabilityTracker->computeDistance(targetManipulability);
543  }
544  else
545  {
546  nullspaceTorque = knull * (nullSpaceJointsVec - qpos) - dnull * qvel;
547  }
548 
549  Eigen::MatrixXf jtpinv = ik->computePseudoInverseJacobianMatrix(jacobi.transpose(), 2.0);
550  Eigen::VectorXf jointDesiredTorques = jacobi.transpose() * jointControlWrench + (I - jacobi.transpose() * jtpinv) * nullspaceTorque;
551 
552  // torque filter (maybe)
553  for (size_t i = 0; i < targets.size(); ++i)
554  {
555  targets.at(i)->torque = jointDesiredTorques(i);
556 
557  if (!targets.at(i)->isValid())
558  {
559  targets.at(i)->torque = 0.0f;
560  }
561  else
562  {
563  if (fabs(targets.at(i)->torque) > fabs(cfg->maxJointTorque))
564  {
565  targets.at(i)->torque = fabs(cfg->maxJointTorque) * (targets.at(i)->torque / fabs(targets.at(i)->torque));
566  }
567  }
568  }
569 
570  debugRT.getWriteBuffer().manidist = manidist;
571 
572  debugRT.commitWrite();
573 
574 
575  }
576 
577 
578  void NJointPeriodicTSDMPCompliantController::learnDMPFromFiles(const Ice::StringSeq& fileNames, const Ice::Current&)
579  {
580  ARMARX_INFO << "Learning DMP ... ";
581 
582  LockGuardType guard {controllerMutex};
583  dmpCtrl->learnDMPFromFiles(fileNames);
584 
585  }
586 
587  void NJointPeriodicTSDMPCompliantController::learnDMPFromTrajectory(const TrajectoryBasePtr& trajectory, const Ice::Current&)
588  {
589  ARMARX_INFO << "Learning DMP ... ";
590  ARMARX_CHECK_EXPRESSION(trajectory);
591  TrajectoryPtr dmpTraj = TrajectoryPtr::dynamicCast(trajectory);
592  ARMARX_CHECK_EXPRESSION(dmpTraj);
593 
594  LockGuardType guard {controllerMutex};
595  dmpCtrl->learnDMPFromTrajectory(dmpTraj);
596 
597  }
598 
600  {
601  LockGuardType guard {controllerMutex};
602  dmpCtrl->setSpeed(times);
603  }
604 
605 
606  void NJointPeriodicTSDMPCompliantController::setGoals(const Ice::DoubleSeq& goals, const Ice::Current& ice)
607  {
608  LockGuardType guard {controllerMutex};
609  dmpCtrl->setGoalPoseVec(goals);
610  }
611 
613  {
614  LockGuardType guard {controllerMutex};
615  dmpCtrl->setAmplitude(amp);
616  }
617 
618  void NJointPeriodicTSDMPCompliantController::setTargetForceInRootFrame(float targetForce, const Ice::Current&)
619  {
621  user2rtData.getWriteBuffer().targetForce = targetForce;
622  user2rtData.commitWrite();
623  }
624 
625  void NJointPeriodicTSDMPCompliantController::runDMP(const Ice::DoubleSeq& goals, Ice::Double tau, const Ice::Current&)
626  {
627  firstRun = true;
628  while (firstRun || rt2UserData.getUpToDateReadBuffer().waitTimeForCalibration < cfg->waitTimeForCalibration)
629  {
630  usleep(100);
631  }
632 
633 
634  Eigen::Matrix4f pose = rt2UserData.getUpToDateReadBuffer().currentTcpPose;
635 
636  LockGuardType guard {controllerMutex};
637  dmpCtrl->prepareExecution(dmpCtrl->eigen4f2vec(pose), goals);
638  dmpCtrl->setSpeed(tau);
639 
640  ARMARX_IMPORTANT << "run DMP";
641  started = true;
642  dmpRunning = false;
643  }
644 
645 
647  {
648  std::string datafieldName;
649  std::string debugName = "Periodic";
650  StringVariantBaseMap datafields;
651 
652  Eigen::Matrix4f targetPoseDebug = debugRT.getUpToDateReadBuffer().targetPose;
653  datafields["target_x"] = new Variant(targetPoseDebug(0, 3));
654  datafields["target_y"] = new Variant(targetPoseDebug(1, 3));
655  datafields["target_z"] = new Variant(targetPoseDebug(2, 3));
656 
657  Eigen::Matrix4f currentPoseDebug = debugRT.getUpToDateReadBuffer().currentPose;
658  datafields["current_x"] = new Variant(currentPoseDebug(0, 3));
659  datafields["current_y"] = new Variant(currentPoseDebug(1, 3));
660  datafields["current_z"] = new Variant(currentPoseDebug(2, 3));
661 
662  Eigen::Vector3f filteredForce = debugRT.getUpToDateReadBuffer().filteredForce;
663  datafields["filteredforce_x"] = new Variant(filteredForce(0));
664  datafields["filteredforce_y"] = new Variant(filteredForce(1));
665  datafields["filteredforce_z"] = new Variant(filteredForce(2));
666 
667 
668  Eigen::Vector3f reactForce = debugRT.getUpToDateReadBuffer().reactForce;
669  datafields["reactForce_x"] = new Variant(reactForce(0));
670  datafields["reactForce_y"] = new Variant(reactForce(1));
671  datafields["reactForce_z"] = new Variant(reactForce(2));
672 
673  Eigen::VectorXf targetVel = debugRT.getUpToDateReadBuffer().targetVel;
674  datafields["targetVel_x"] = new Variant(targetVel(0));
675  datafields["targetVel_y"] = new Variant(targetVel(1));
676  datafields["targetVel_z"] = new Variant(targetVel(2));
677 
678  Eigen::VectorXf currentVel = debugRT.getUpToDateReadBuffer().currentTwist;
679  datafields["currentVel_x"] = new Variant(currentVel(0));
680  datafields["currentVel_y"] = new Variant(currentVel(1));
681  datafields["currentVel_z"] = new Variant(currentVel(2));
682 
683  Eigen::Vector3f adaptK = debugRT.getUpToDateReadBuffer().adaptK;
684  datafields["adaptK_x"] = new Variant(adaptK(0));
685  datafields["adaptK_y"] = new Variant(adaptK(1));
686 
687  datafields["canVal"] = new Variant(debugOutputData.getUpToDateReadBuffer().currentCanVal);
688  datafields["deltaT"] = new Variant(debugOutputData.getUpToDateReadBuffer().deltaT);
689 
690  datafields["PhaseStop"] = new Variant(debugRT.getUpToDateReadBuffer().isPhaseStop);
691  datafields["manidist"] = new Variant(debugRT.getUpToDateReadBuffer().manidist);
692 
693 
694  // datafields["targetVel_rx"] = new Variant(targetVel(3));
695  // datafields["targetVel_ry"] = new Variant(targetVel(4));
696  // datafields["targetVel_rz"] = new Variant(targetVel(5));
697 
698  // auto values = debugOutputData.getUpToDateReadBuffer().latestTargetVelocities;
699  // for (auto& pair : values)
700  // {
701  // datafieldName = pair.first + "_" + debugName;
702  // datafields[datafieldName] = new Variant(pair.second);
703  // }
704 
705  // auto currentPose = debugOutputData.getUpToDateReadBuffer().currentPose;
706  // for (auto& pair : currentPose)
707  // {
708  // datafieldName = pair.first + "_" + debugName;
709  // datafields[datafieldName] = new Variant(pair.second);
710  // }
711 
712  // datafieldName = "canVal_" + debugName;
713  // datafields[datafieldName] = new Variant(debugOutputData.getUpToDateReadBuffer().currentCanVal);
714  // datafieldName = "mpcFactor_" + debugName;
715  // datafields[datafieldName] = new Variant(debugOutputData.getUpToDateReadBuffer().mpcFactor);
716  // datafieldName = "error_" + debugName;
717  // datafields[datafieldName] = new Variant(debugOutputData.getUpToDateReadBuffer().error);
718  // datafieldName = "posError_" + debugName;
719  // datafields[datafieldName] = new Variant(debugOutputData.getUpToDateReadBuffer().posError);
720  // datafieldName = "oriError_" + debugName;
721  // datafields[datafieldName] = new Variant(debugOutputData.getUpToDateReadBuffer().oriError);
722  // datafieldName = "deltaT_" + debugName;
723  // datafields[datafieldName] = new Variant(debugOutputData.getUpToDateReadBuffer().deltaT);
724 
725  datafieldName = "PeriodicDMP";
726  debugObs->setDebugChannel(datafieldName, datafields);
727  }
728 
729 
730 
732  {
733  ARMARX_INFO << "stopped ...";
734  }
735 
736 
737 
738 }
armarx::NJointControllerWithTripleBuffer< NJointPeriodicTSDMPCompliantControllerControlData >::reinitTripleBuffer
void reinitTripleBuffer(const NJointPeriodicTSDMPCompliantControllerControlData &initial)
Definition: NJointControllerWithTripleBuffer.h:68
armarx::ControlTargetBase::asA
const T * asA() const
Definition: ControlTargetBase.h:76
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:224
armarx::control::deprecated_njoint_mp_controller::tsvmp::PhaseStopParams::Kori
float Kori
Definition: TaskSpaceVMP.h:47
armarx::control::deprecated_njoint_mp_controller::tsvmp::PhaseStopParams::Dpos
float Dpos
Definition: TaskSpaceVMP.h:46
armarx::control::deprecated_njoint_mp_controller::task_space::NJointPeriodicTSDMPCompliantController::learnDMPFromTrajectory
void learnDMPFromTrajectory(const TrajectoryBasePtr &trajectory, const Ice::Current &)
Definition: NJointPeriodicTSDMPCompliantController.cpp:587
armarx::control::deprecated_njoint_mp_controller::task_space::NJointPeriodicTSDMPCompliantController::getClassName
std::string getClassName(const Ice::Current &) const
Definition: NJointPeriodicTSDMPCompliantController.cpp:214
armarx::TripleBuffer::getWriteBuffer
T & getWriteBuffer()
Definition: TripleBuffer.h:90
armarx::NJointControllerBase::useSynchronizedRtRobot
const VirtualRobot::RobotPtr & useSynchronizedRtRobot(bool updateCollisionModel=false)
Requests a VirtualRobot for use in rtRun *.
Definition: NJointController.cpp:293
armarx::NJointControllerWithTripleBuffer< NJointPeriodicTSDMPCompliantControllerControlData >::rtGetControlStruct
const NJointPeriodicTSDMPCompliantControllerControlData & rtGetControlStruct() const
Definition: NJointControllerWithTripleBuffer.h:32
armarx::control::deprecated_njoint_mp_controller::tsvmp::TaskSpaceDMPControllerConfig::DMPKernelSize
int DMPKernelSize
Definition: TaskSpaceVMP.h:54
armarx::StringVariantBaseMap
std::map< std::string, VariantBasePtr > StringVariantBaseMap
Definition: ManagedIceObject.h:111
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
armarx::control::deprecated_njoint_mp_controller::task_space::NJointPeriodicTSDMPCompliantControllerControlData::targetTSVel
Eigen::VectorXf targetTSVel
Definition: NJointPeriodicTSDMPCompliantController.h:34
armarx::SensorValueBase::asA
const T * asA() const
Definition: SensorValueBase.h:82
armarx::SensorValueBase
The SensorValueBase class.
Definition: SensorValueBase.h:40
armarx::ControlTargetBase
Brief description of class JointControlTargetBase.
Definition: ControlTargetBase.h:47
armarx::TripleBuffer::commitWrite
void commitWrite()
Definition: TripleBuffer.h:146
armarx::control::deprecated_njoint_mp_controller::task_space::NJointPeriodicTSDMPCompliantController::NJointPeriodicTSDMPCompliantController
NJointPeriodicTSDMPCompliantController(const RobotUnitPtr &, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &)
Definition: NJointPeriodicTSDMPCompliantController.cpp:9
armarx::NJointControllerBase::useControlTarget
ControlTargetBase * useControlTarget(const std::string &deviceName, const std::string &controlMode)
Declares to calculate the ControlTarget for the given ControlDevice in the given ControlMode when rtR...
Definition: NJointController.cpp:410
armarx::control::deprecated_njoint_mp_controller::task_space
Definition: DeprecatedNJointPeriodicTSDMPCompliantController.cpp:6
armarx::control::deprecated_njoint_mp_controller::task_space::NJointPeriodicTSDMPCompliantController::onInitNJointController
void onInitNJointController()
Definition: NJointPeriodicTSDMPCompliantController.cpp:169
armarx::CycleUtil
This util class helps with keeping a cycle time during a control cycle.
Definition: CycleUtil.h:40
armarx::ManagedIceObject::getState
int getState() const
Retrieve current state of the ManagedIceObject.
Definition: ManagedIceObject.cpp:725
ARMARX_CHECK_LESS
#define ARMARX_CHECK_LESS(lhs, rhs)
This macro evaluates whether lhs is less (<) than rhs and if it turns out to be false it will throw a...
Definition: ExpressionException.h:102
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
armarx::control::deprecated_njoint_mp_controller::task_space::NJointPeriodicTSDMPCompliantControllerControlData
Definition: NJointPeriodicTSDMPCompliantController.h:31
armarx::control::deprecated_njoint_mp_controller::tsvmp::TaskSpaceDMPControllerConfig
Definition: TaskSpaceVMP.h:52
armarx::control::deprecated_njoint_mp_controller::tsvmp::TaskSpaceDMPControllerConfig::phaseStopParas
PhaseStopParams phaseStopParas
Definition: TaskSpaceVMP.h:60
armarx::control::deprecated_njoint_mp_controller::task_space::NJointPeriodicTSDMPCompliantController::onDisconnectNJointController
void onDisconnectNJointController()
Definition: NJointPeriodicTSDMPCompliantController.cpp:731
armarx::NJointControllerWithTripleBuffer< NJointPeriodicTSDMPCompliantControllerControlData >::getWriterControlStruct
NJointPeriodicTSDMPCompliantControllerControlData & getWriterControlStruct()
Definition: NJointControllerWithTripleBuffer.h:54
armarx::control::deprecated_njoint_mp_controller::tsvmp::PhaseStopParams::goDist
float goDist
Definition: TaskSpaceVMP.h:41
armarx::NJointControllerWithTripleBuffer< NJointPeriodicTSDMPCompliantControllerControlData >::LockGuardType
std::lock_guard< std::recursive_mutex > LockGuardType
Definition: NJointControllerWithTripleBuffer.h:14
armarx::SensorValueForceTorque::force
Eigen::Vector3f force
Definition: SensorValueForceTorque.h:35
armarx::VariantType::Quaternion
const VariantTypeId Quaternion
Definition: Pose.h:39
armarx::control::deprecated_njoint_mp_controller::tsvmp::TaskSpaceDMPControllerConfig::motionTimeDuration
float motionTimeDuration
Definition: TaskSpaceVMP.h:59
IceInternal::Handle< Trajectory >
armarx::NJointControllerBase::rtGetRobot
const VirtualRobot::RobotPtr & rtGetRobot()
TODO make protected and use attorneys.
Definition: NJointControllerBase.h:845
armarx::control::deprecated_njoint_mp_controller::tsvmp::PhaseStopParams::backDist
float backDist
Definition: TaskSpaceVMP.h:42
armarx::control::deprecated_njoint_mp_controller::tsvmp::PhaseStopParams::maxValue
float maxValue
Definition: TaskSpaceVMP.h:43
armarx::control::deprecated_njoint_mp_controller::task_space::registrationControllerNJointPeriodicTSDMPCompliantController
NJointControllerRegistration< NJointPeriodicTSDMPCompliantController > registrationControllerNJointPeriodicTSDMPCompliantController("NJointPeriodicTSDMPCompliantController")
armarx::detail::ControlThreadOutputBufferEntry
Definition: ControlThreadOutputBuffer.h:177
armarx::VariantType::Double
const VariantTypeId Double
Definition: Variant.h:919
armarx::control::deprecated_njoint_mp_controller::tsvmp::PhaseStopParams::Dori
float Dori
Definition: TaskSpaceVMP.h:48
NJointPeriodicTSDMPCompliantController.h
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:523
armarx::control::deprecated_njoint_mp_controller::task_space::NJointPeriodicTSDMPCompliantController::controllerRun
void controllerRun()
Definition: NJointPeriodicTSDMPCompliantController.cpp:219
armarx::NJointControllerBase::isControllerActive
bool isControllerActive(const Ice::Current &=Ice::emptyCurrent) const final override
Definition: NJointControllerBase.h:777
armarx::NJointControllerBase::runTask
void runTask(const std::string &taskName, Task &&task)
Executes a given task in a separate thread from the Application ThreadPool.
Definition: NJointControllerBase.h:753
armarx::NJointControllerWithTripleBuffer< NJointPeriodicTSDMPCompliantControllerControlData >::rtUpdateControlStruct
bool rtUpdateControlStruct()
Definition: NJointControllerWithTripleBuffer.h:38
armarx::control::deprecated_njoint_mp_controller::task_space::NJointPeriodicTSDMPCompliantController::learnDMPFromFiles
void learnDMPFromFiles(const Ice::StringSeq &fileNames, const Ice::Current &)
Definition: NJointPeriodicTSDMPCompliantController.cpp:578
armarx::NJointControllerWithTripleBuffer< NJointPeriodicTSDMPCompliantControllerControlData >::writeControlStruct
void writeControlStruct()
Definition: NJointControllerWithTripleBuffer.h:44
ArmarXObjectScheduler.h
armarx::control::deprecated_njoint_mp_controller::task_space::NJointPeriodicTSDMPCompliantController::setSpeed
void setSpeed(Ice::Double times, const Ice::Current &)
Definition: NJointPeriodicTSDMPCompliantController.cpp:599
armarx::NJointControllerWithTripleBuffer< NJointPeriodicTSDMPCompliantControllerControlData >::controlDataMutex
MutexType controlDataMutex
Definition: NJointControllerWithTripleBuffer.h:73
armarx::control::deprecated_njoint_mp_controller::tsvmp::TaskSpaceDMPControllerConfig::DMPAmplitude
float DMPAmplitude
Definition: TaskSpaceVMP.h:57
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::control::deprecated_njoint_mp_controller::tsvmp::PhaseStopParams::slop
float slop
Definition: TaskSpaceVMP.h:44
armarx::control::deprecated_njoint_mp_controller::tsvmp::PhaseStopParams::Kpos
float Kpos
Definition: TaskSpaceVMP.h:45
armarx::control::deprecated_njoint_mp_controller::task_space::NJointPeriodicTSDMPCompliantController::runDMP
void runDMP(const Ice::DoubleSeq &goals, Ice::Double tau, const Ice::Current &)
Definition: NJointPeriodicTSDMPCompliantController.cpp:625
GfxTL::Matrix3f
MatrixXX< 3, 3, float > Matrix3f
Definition: MatrixXX.h:600
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:601
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
float
#define float
Definition: 16_Level.h:22
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::control::deprecated_njoint_mp_controller::tsvmp::TaskSpaceDMPControllerConfig::DMPStyle
std::string DMPStyle
Definition: TaskSpaceVMP.h:56
IceInternal::ProxyHandle<::IceProxy::armarx::DebugDrawerInterface >
armarx::control::deprecated_njoint_mp_controller::tsvmp::TaskSpaceDMPControllerConfig::DMPMode
std::string DMPMode
Definition: TaskSpaceVMP.h:55
armarx::control::deprecated_njoint_mp_controller::task_space::NJointPeriodicTSDMPCompliantController::setAmplitude
void setAmplitude(Ice::Double amp, const Ice::Current &)
Definition: NJointPeriodicTSDMPCompliantController.cpp:612
Eigen::Matrix< float, 6, 1 >
armarx::control::deprecated_njoint_mp_controller::tsvmp::PhaseStopParams::mm2radi
float mm2radi
Definition: TaskSpaceVMP.h:49
armarx::control::deprecated_njoint_mp_controller::task_space::NJointPeriodicTSDMPCompliantController::onPublish
virtual void onPublish(const SensorAndControl &, const DebugDrawerInterfacePrx &, const DebugObserverInterfacePrx &)
Definition: NJointPeriodicTSDMPCompliantController.cpp:646
armarx::control::deprecated_njoint_mp_controller::task_space::NJointPeriodicTSDMPCompliantController::setTargetForceInRootFrame
void setTargetForceInRootFrame(Ice::Float force, const Ice::Current &)
Definition: NJointPeriodicTSDMPCompliantController.cpp:618
armarx::navigation::core::Position
Eigen::Vector3f Position
Definition: basic_types.h:36
armarx::TripleBuffer::getUpToDateReadBuffer
const T & getUpToDateReadBuffer() const
Definition: TripleBuffer.h:108
ARMARX_CHECK_EQUAL
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
Definition: ExpressionException.h:130
armarx::SensorValueForceTorque
Definition: SensorValueForceTorque.h:31
armarx::TripleBuffer::reinitAllBuffers
std::enable_if< std::is_copy_constructible< U >::value >::type reinitAllBuffers(const T &init)
Definition: TripleBuffer.h:153
armarx::control::deprecated_njoint_mp_controller::tsvmp::TaskSpaceDMPController
Brief description of class TaskSpaceDMPController.
Definition: TaskSpaceVMP.h:83
armarx::ManagedIceObject::getObjectScheduler
ArmarXObjectSchedulerPtr getObjectScheduler() const
Definition: ManagedIceObject.cpp:731
armarx::NJointControllerBase::useSensorValue
const SensorValueBase * useSensorValue(const std::string &sensorDeviceName) const
Get a const ptr to the given SensorDevice's SensorValue.
Definition: NJointController.cpp:383
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:18
armarx::control::deprecated_njoint_mp_controller::task_space::NJointPeriodicTSDMPCompliantController::setGoals
void setGoals(const Ice::DoubleSeq &goals, const Ice::Current &)
Definition: NJointPeriodicTSDMPCompliantController.cpp:606
armarx::control::deprecated_njoint_mp_controller::task_space::NJointPeriodicTSDMPCompliantController::rtRun
void rtRun(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration)
TODO make protected and use attorneys.
Definition: NJointPeriodicTSDMPCompliantController.cpp:279
norm
double norm(const Point &a)
Definition: point.hpp:94