3 #include <VirtualRobot/IK/DifferentialIK.h>
4 #include <VirtualRobot/MathTools.h>
5 #include <VirtualRobot/Nodes/RobotNode.h>
6 #include <VirtualRobot/Robot.h>
7 #include <VirtualRobot/RobotNodeSet.h>
22 NJointControllerRegistration<NJointAnomalyDetectionAdaptiveWipingController>
24 "NJointAnomalyDetectionAdaptiveWipingController");
28 const armarx::NJointControllerConfigPtr& config,
32 cfg = NJointAnomalyDetectionAdaptiveWipingControllerConfigPtr::dynamicCast(config);
34 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(cfg->nodeSetName);
37 for (
size_t i = 0; i < rns->getSize(); ++i)
39 std::string jointName = rns->getNode(i)->getName();
42 targets.push_back(ct->
asA<ControlTarget1DoFActuatorTorque>());
44 const SensorValue1DoFActuatorVelocity* velocitySensor =
45 sv->
asA<SensorValue1DoFActuatorVelocity>();
46 const SensorValue1DoFActuatorPosition* positionSensor =
47 sv->
asA<SensorValue1DoFActuatorPosition>();
49 velocitySensors.push_back(velocitySensor);
50 positionSensors.push_back(positionSensor);
53 useDMPInGlobalFrame = cfg->useDMPInGlobalFrame;
57 nodeSetName = cfg->nodeSetName;
58 ik.reset(
new VirtualRobot::DifferentialIK(
59 rns, rns->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
65 taskSpaceDMPConfig.
DMPMode =
"Linear";
66 taskSpaceDMPConfig.
DMPStyle =
"Periodic";
77 lastCanVal = cfg->timeDuration;
83 for (
size_t i = 0; i < 6; ++i)
94 velocityHorizon = cfg->velocityHorizon;
97 frictionHorizon = cfg->frictionHorizon;
98 estimatedFriction << 0.0, 0.0;
99 lastForceInToolXY.setZero();
106 kpos << cfg->Kpos[0], cfg->Kpos[1], cfg->Kpos[2];
107 dpos << cfg->Dpos[0], cfg->Dpos[1], cfg->Dpos[2];
108 kori << cfg->Kori[0], cfg->Kori[1], cfg->Kori[2];
109 dori << cfg->Dori[0], cfg->Dori[1], cfg->Dori[2];
111 isForceCtrlInForceDir = cfg->isForceCtrlInForceDir;
112 isForceControlEnabled = cfg->isForceControlEnabled;
113 isRotControlEnabled = cfg->isRotControlEnabled;
114 isTorqueControlEnabled = cfg->isTorqueControlEnabled;
115 isLCRControlEnabled = cfg->isLCRControlEnabled;
117 cfg->pidForce[0], cfg->pidForce[1], cfg->pidForce[2], cfg->pidForce[3]));
119 new PIDController(cfg->pidRot[0], cfg->pidRot[1], cfg->pidRot[2], cfg->pidRot[3]));
121 cfg->pidTorque[0], cfg->pidTorque[1], cfg->pidTorque[2], cfg->pidTorque[3]));
123 new PIDController(cfg->pidLCR[0], cfg->pidLCR[1], cfg->pidLCR[2], cfg->pidLCR[3]));
124 adaptKpForce = cfg->pidForce[0];
125 adaptKpRot = cfg->pidRot[0];
127 knull.setZero(targets.size());
128 dnull.setZero(targets.size());
130 for (
size_t i = 0; i < targets.size(); ++i)
132 knull(i) = cfg->Knull.at(i);
133 dnull(i) = cfg->Dnull.at(i);
136 nullSpaceJointsVec.resize(cfg->desiredNullSpaceJointValues.size());
137 for (
size_t i = 0; i < cfg->desiredNullSpaceJointValues.size(); ++i)
139 nullSpaceJointsVec(i) = cfg->desiredNullSpaceJointValues.at(i);
144 robUnit->getSensorDevice(cfg->forceSensorName)->getSensorValue();
150 currentForceOffset.setZero();
151 forceOffset << cfg->ftOffset[0], cfg->ftOffset[1], cfg->ftOffset[2];
152 torqueOffset << cfg->ftOffset[3], cfg->ftOffset[4], cfg->ftOffset[5];
154 handMass = cfg->handMass;
155 handCOM << cfg->handCOM[0], cfg->handCOM[1], cfg->handCOM[2];
158 filteredForce.setZero();
159 filteredTorque.setZero();
160 filteredFTCommand.setZero();
161 filteredForceInRoot.setZero();
162 filteredTorqueInRoot.setZero();
163 targetFTInToolFrame.setZero();
165 UserToRTData initUserData;
166 initUserData.targetForce = 0;
169 oriToolDir << 0, 0, 1;
170 gravityInRoot << 0, 0, -9.8;
172 qvel_filtered.setZero(targets.size());
199 abnormalFlag =
false;
200 lastAbnormalFlag =
false;
201 positionOffset.setZero();
214 RTToControllerData initSensorData;
215 initSensorData.deltaT = 0;
216 initSensorData.currentTime = 0;
217 initSensorData.currentPose = tcp->getPoseInRootFrame();
218 initSensorData.currentTwist.setZero();
219 initSensorData.isPhaseStop =
false;
222 RTToUserData initInterfaceData;
223 initInterfaceData.currentTcpPose = tcp->getPoseInRootFrame();
224 initInterfaceData.waitTimeForCalibration = 0;
229 runTask(
"NJointAnomalyDetectionAdaptiveWipingController",
234 while (
getState() == eManagedIceObjectStarted)
240 c.waitForCycleDuration();
248 return "NJointAnomalyDetectionAdaptiveWipingController";
264 Eigen::VectorXf targetVels(6);
269 targetVels.setZero();
280 dmpCtrl->flow(deltaT, currentPose, currentTwist);
282 targetVels = dmpCtrl->getTargetVelocity();
283 targetDMPPose = dmpCtrl->getTargetPoseMat();
285 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"x_vel"] = targetVels(0);
286 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"y_vel"] = targetVels(1);
287 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"z_vel"] = targetVels(2);
288 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"roll_vel"] = targetVels(3);
289 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"pitch_vel"] = targetVels(4);
290 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"yaw_vel"] = targetVels(5);
291 debugOutputData.
getWriteBuffer().currentPose[
"currentPose_x"] = currentPose(0, 3);
292 debugOutputData.
getWriteBuffer().currentPose[
"currentPose_y"] = currentPose(1, 3);
293 debugOutputData.
getWriteBuffer().currentPose[
"currentPose_z"] = currentPose(2, 3);
295 VirtualRobot::MathTools::eigen4f2quat(currentPose);
296 debugOutputData.
getWriteBuffer().currentPose[
"currentPose_qw"] = currentQ.w;
297 debugOutputData.
getWriteBuffer().currentPose[
"currentPose_qx"] = currentQ.x;
298 debugOutputData.
getWriteBuffer().currentPose[
"currentPose_qy"] = currentQ.y;
299 debugOutputData.
getWriteBuffer().currentPose[
"currentPose_qz"] = currentQ.z;
300 debugOutputData.
getWriteBuffer().currentCanVal = dmpCtrl->debugData.canVal;
301 debugOutputData.
getWriteBuffer().mpcFactor = dmpCtrl->debugData.mpcFactor;
302 debugOutputData.
getWriteBuffer().error = dmpCtrl->debugData.poseError;
303 debugOutputData.
getWriteBuffer().posError = dmpCtrl->debugData.posiError;
304 debugOutputData.
getWriteBuffer().oriError = dmpCtrl->debugData.oriError;
321 double deltaT = timeSinceLastIteration.toSecondsDouble();
322 float dTf = (
float)deltaT;
327 Eigen::Vector3f currentToolDir;
328 currentToolDir.setZero();
329 Eigen::MatrixXf jacobi =
330 ik->getJacobianMatrix(tcp, VirtualRobot::IKSolver::CartesianSelection::All);
332 Eigen::VectorXf qpos(positionSensors.size());
333 Eigen::VectorXf qvel(velocitySensors.size());
334 for (
size_t i = 0; i < positionSensors.size(); ++i)
336 qpos(i) = positionSensors[i]->position;
337 qvel(i) = velocitySensors[i]->velocity;
340 qvel_filtered = (1 - cfg->velFilter) * qvel_filtered + cfg->velFilter * qvel;
341 Eigen::VectorXf currentTwist = jacobi * qvel_filtered;
343 velocityHorizonList.push_back(currentTwist);
344 if (velocityHorizonList.size() > velocityHorizon)
346 velocityHorizonList.pop_front();
349 Eigen::VectorXf targetVel(6);
350 Eigen::Vector3f axis;
351 Eigen::Vector3f forceInToolFrame;
352 Eigen::Vector3f torqueInToolFrame;
354 Eigen::Vector3f velPInToolFrame;
357 forceInToolFrame.setZero();
358 torqueInToolFrame.setZero();
359 targetFTInRootFrame.setZero();
360 velPInToolFrame.setZero();
362 bool isPhaseStop =
false;
364 if (firstRun || !dmpRunning)
366 initHandPose = currentPose;
367 lastPosition = currentPose.block<2, 1>(0, 3);
368 targetPose = currentPose;
370 filteredForce.setZero();
371 Eigen::Vector3f currentForce = forceSensor->
force - forceOffset;
374 ->getRobotNode(cfg->forceFrameName)
375 ->getPoseInRootFrame()
377 Eigen::Vector3f gravityInForceFrame = forceFrameOri.transpose() * gravityInRoot;
378 Eigen::Vector3f handGravity = handMass * gravityInForceFrame;
379 currentForce = currentForce - handGravity;
381 currentForceOffset = 0.1 * currentForceOffset + 0.9 * currentForce;
382 origHandOri = currentPose.block<3, 3>(0, 0);
383 toolTransform = origHandOri.transpose();
392 Eigen::Matrix3f currentToolOri = currentPose.block<3, 3>(0, 0) * toolTransform;
396 targetVel.head<3>() = currentToolOri * targetVel.head<3>();
397 targetVel.tail<3>() = currentToolOri * targetVel.tail<3>();
400 if (canVal - lastCanVal > 0.9 * cfg->timeDuration)
408 Eigen::Vector3f currentForce = forceSensor->
force - forceOffset - currentForceOffset;
411 ->getRobotNode(cfg->forceFrameName)
412 ->getPoseInRootFrame()
414 Eigen::Vector3f gravityInForceFrame = forceFrameOri.transpose() * gravityInRoot;
415 Eigen::Vector3f handGravity = handMass * gravityInForceFrame;
417 currentForce = currentForce - handGravity;
419 (1 - cfg->forceFilter) * filteredForce + cfg->forceFilter * currentForce;
421 Eigen::Vector3f currentTorque = forceSensor->
torque - torqueOffset;
422 Eigen::Vector3f handTorque = handCOM.cross(gravityInForceFrame);
423 currentTorque = currentTorque - handTorque;
425 (1 - cfg->forceFilter) * filteredTorque + cfg->forceFilter * currentTorque;
427 Eigen::Vector3f forceInRootForFricEst = forceFrameOri * filteredForce;
428 Eigen::Vector3f forceInToolForFricEst =
429 currentToolOri.transpose() * forceInRootForFricEst;
431 for (
size_t i = 0; i < 3; ++i)
433 if (fabs(filteredForce(i)) > cfg->forceDeadZone)
436 (filteredForce(i) / fabs(filteredForce(i))) * cfg->forceDeadZone;
440 filteredForce(i) = 0;
444 filteredForceInRoot = forceFrameOri * filteredForce;
445 filteredTorqueInRoot = forceFrameOri * filteredTorque;
448 forceInToolFrame = currentToolOri.transpose() * filteredForceInRoot;
450 torqueInToolFrame = currentToolOri.transpose() * filteredTorqueInRoot;
451 velPInToolFrame = currentToolOri.transpose() * currentTwist.head<3>();
457 if (abnormalFlag ==
true && filteredForceInRoot.norm() > cfg->dragForceDeadZone)
461 adaptKpForce *= cfg->adaptRateDecrease;
462 adaptKpRot *= cfg->adaptRateDecreaseRot;
463 forcePID->Kp = adaptKpForce;
464 torquePID->Kp = adaptKpRot;
471 adaptK *= cfg->adaptRateDecrease;
472 adaptD *= cfg->adaptRateDecrease;
473 if (cfg->isAdaptOriImpEnabled)
475 adaptKOri *= cfg->adaptRateDecrease;
476 adaptDOri *= cfg->adaptRateDecrease;
478 adaptKNull *= cfg->adaptRateDecrease;
479 adaptDNull *= cfg->adaptRateDecrease;
481 positionOffset.setZero();
489 fmin(adaptKpForce + dTf * cfg->increaseKpForceCoeff, cfg->pidForce[0]);
490 adaptKpRot = fmin(adaptKpRot + dTf * cfg->increaseKpRotCoeff, cfg->pidRot[0]);
493 forcePID->Kp = adaptKpForce;
494 torquePID->Kp = adaptKpRot;
495 for (
int i = 0; i < 3; i++)
497 adaptK(i) = fmin(adaptK(i) + fabs(dTf * cfg->adaptCoeff), kpos(i));
498 adaptD(i) = fmin(adaptD(i) + fabs(dTf * cfg->adaptCoeffKdImpIncrease), dpos(i));
499 if (cfg->isAdaptOriImpEnabled)
502 fmin(adaptKOri(i) + fabs(dTf * cfg->increaseKpOriCoeff), kori(i));
504 fmin(adaptDOri(i) + fabs(dTf * cfg->increaseKdOriCoeff), dori(i));
507 for (
size_t i = 0; i < targets.size(); i++)
510 fmin(adaptKNull(i) + fabs(dTf * cfg->increaseKpNullCoeff), knull(i));
512 fmin(adaptDNull(i) + fabs(dTf * cfg->increaseKdNullCoeff), dnull(i));
519 if (!isContactedOnce && fabs(forceInToolFrame(2)) > targetForce)
521 isContactedOnce =
true;
523 if (cfg->loseContactDetectionEnabled && isContactedOnce)
525 if (abnormalFlag && !lastAbnormalFlag)
527 startLoseContactDetection =
true;
528 loseContactCounter = 0;
531 if (startLoseContactDetection && loseContactCounter < cfg->loseContactCounterMax)
533 forceIntegral += forceInToolFrame.norm() * deltaT;
534 loseContactCounter++;
536 if (loseContactCounter >= cfg->loseContactCounterMax &&
537 forceIntegral < cfg->loseContactForceIntThreshold)
539 isLoseContact =
true;
541 lastAbnormalFlag = abnormalFlag;
556 Eigen::Vector2f v_xy;
557 Eigen::Vector2f f_xy;
558 v_xy << velPInToolFrame(0), velPInToolFrame(1);
559 f_xy << forceInToolForFricEst(0), forceInToolForFricEst(1);
560 f_xy = cfg->fricEstiFilter * f_xy + (1 - cfg->fricEstiFilter) * lastForceInToolXY;
561 lastForceInToolXY = f_xy;
563 if (wipingCounter > 0)
565 if (v_xy.norm() > cfg->velNormThreshold &&
566 fabs(forceInToolForFricEst(2) - targetForce) < 0.5 * targetForce)
568 recordFrictionNorm.push_back(f_xy.norm());
569 recordForceNormToSurface.push_back(forceInToolForFricEst(2));
571 if (recordFrictionNorm.size() > frictionHorizon)
573 recordFrictionNorm.pop_front();
574 recordForceNormToSurface.pop_front();
575 float dotProduct = 0.0;
576 float normSquare = 0.0;
577 for (
size_t i = 0; i < recordFrictionNorm.size(); i++)
579 dotProduct += (recordFrictionNorm[i] * recordForceNormToSurface[i]);
580 normSquare += (recordForceNormToSurface[i] * recordForceNormToSurface[i]);
584 float mu_tmp = dotProduct / normSquare;
587 mu = fmax(fmin(mu, mu_tmp), safeFrictionConeLowerLimit);
590 if (v_xy.norm() > cfg->velNormThreshold)
592 estimatedFriction = -v_xy * mu * forceInToolForFricEst(2) / v_xy.norm();
599 if (isForceCtrlInForceDir)
601 forcePID->update(deltaT, forceInToolFrame.norm(), targetForce);
605 forcePID->update(deltaT, forceInToolFrame(2), targetForce);
607 torquePID->update(deltaT, torqueInToolFrame(1), 0.0);
611 currentToolDir = currentToolOri * oriToolDir;
612 for (
int i = 3; i < 6; ++i)
617 if (cfg->frictionCone < 0.0)
619 frictionCone = atan(mu);
623 frictionCone = cfg->frictionCone;
625 float adaptedAngularKp = 0.0;
626 Eigen::Vector3f angularDiff;
627 angularDiff.setZero();
629 if (filteredForceInRoot.norm() > fabs(cfg->minimumReactForce))
631 Eigen::Vector3f toolYDir;
632 toolYDir << 0, 1.0, 0;
633 Eigen::Vector3f toolYDirInRoot = currentToolOri * toolYDir;
634 Eigen::Vector3f projectedFilteredForceInRoot =
635 filteredForceInRoot - filteredForceInRoot.dot(toolYDirInRoot) * toolYDirInRoot;
636 Eigen::Vector3f desiredToolDir =
637 projectedFilteredForceInRoot
639 currentToolDir.normalize();
641 axis = currentToolDir.cross(desiredToolDir);
642 axis = axis.normalized();
643 angle = acosf(currentToolDir.dot(desiredToolDir));
655 cfg->pidRot[0] / (1 + exp(10 * (
angle - cfg->rotAngleSigmoid)));
656 adaptedAngularKp = fmin(adaptedAngularKp, cfg->pidRot[0]);
657 rotPID->Kp = adaptedAngularKp;
658 angle -= frictionCone;
664 rotPID->Kp = cfg->pidRot[0];
667 rotPID->update(deltaT,
angle, 0.0);
729 float diff = (targetPose.block<2, 1>(0, 3) - currentPose.block<2, 1>(0, 3)).
norm();
730 if (diff > cfg->phaseDist0)
743 if (isForceControlEnabled)
745 if (isForceCtrlInForceDir)
747 float forcePIDVel = -(
float)forcePID->getControlValue();
748 Eigen::Vector3f targetVelInTool;
749 if (forceInToolFrame.norm() < 1e-4)
751 targetVelInTool << 0, 0, forcePIDVel;
755 targetVelInTool = forceInToolFrame / forceInToolFrame.norm() * forcePIDVel;
757 targetVel.head<3>() += currentToolOri * targetVelInTool;
762 Eigen::Vector3f localVel;
763 localVel << 0, 0, -(
float)forcePID->getControlValue();
764 positionOffset += currentToolOri * localVel * deltaT;
766 targetVel(2) -= (
float)forcePID->getControlValue();
767 targetVel.head<3>() = currentToolOri * targetVel.head<3>();
772 positionOffset.setZero();
775 if (isRotControlEnabled)
779 targetVel(4) -= (
float)rotPID->getControlValue();
781 if (isTorqueControlEnabled)
784 targetVel(4) += (
float)torquePID->getControlValue();
793 rt2UserData.
getWriteBuffer().tcpTranslVel = currentTwist.head<3>();
800 if (useDMPInGlobalFrame)
803 targetPose.block<3, 1>(0, 3) += positionOffset;
807 targetPose.block<3, 1>(0, 3) =
808 targetPose.block<3, 1>(0, 3) + dTf * targetVel.block<3, 1>(0, 0);
810 dTf * targetVel(3), dTf * targetVel(4), dTf * targetVel(5));
811 targetPose.block<3, 3>(0, 0) = rotMat * targetPose.block<3, 3>(0, 0);
815 Eigen::Vector2f currentXY = currentPose.block<2, 1>(0, 3);
816 if ((lastPosition - currentXY).norm() < cfg->changePositionTolerance)
818 changeTimer += deltaT;
822 lastPosition = currentPose.block<2, 1>(0, 3);
826 if (changeTimer > cfg->changeTimerThreshold)
828 targetPose(0, 3) = currentPose(0, 3);
829 targetPose(1, 3) = currentPose(1, 3);
840 targetPose(0, 3) = targetPose(0, 3) > cfg->ws_x[0] ? targetPose(0, 3) : cfg->ws_x[0];
841 targetPose(0, 3) = targetPose(0, 3) < cfg->ws_x[1] ? targetPose(0, 3) : cfg->ws_x[1];
843 targetPose(1, 3) = targetPose(1, 3) > cfg->ws_y[0] ? targetPose(1, 3) : cfg->ws_y[0];
844 targetPose(1, 3) = targetPose(1, 3) < cfg->ws_y[1] ? targetPose(1, 3) : cfg->ws_y[1];
846 targetPose(2, 3) = targetPose(2, 3) > cfg->ws_z[0] ? targetPose(2, 3) : cfg->ws_z[0];
847 targetPose(2, 3) = targetPose(2, 3) < cfg->ws_z[1] ? targetPose(2, 3) : cfg->ws_z[1];
852 jacobi.block<3, 8>(0, 0) = 0.001 * jacobi.block<3, 8>(0, 0);
855 targetPose.block<3, 3>(0, 0) * currentPose.block<3, 3>(0, 0).transpose();
856 Eigen::Vector3f rpy = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
863 taskFTControlCommand.head<3>() =
864 adaptK.cwiseProduct(targetPose.block<3, 1>(0, 3) - currentPose.block<3, 1>(0, 3)) *
866 adaptD.cwiseProduct(-currentTwist.head<3>()) * 0.001 + targetFTInRootFrame.head<3>();
867 taskFTControlCommand.tail<3>() = kori.cwiseProduct(rpy) +
868 dori.cwiseProduct(-currentTwist.tail<3>()) +
869 targetFTInRootFrame.tail<3>();
871 filteredFTCommand = cfg->ftCommandFilter * taskFTControlCommand +
872 (1 - cfg->ftCommandFilter) * filteredFTCommand;
877 Eigen::VectorXf nullspaceTorque =
878 knull.cwiseProduct(nullSpaceJointsVec - qpos) - dnull.cwiseProduct(qvel);
879 Eigen::MatrixXf jtpinv = ik->computePseudoInverseJacobianMatrix(jacobi.transpose(), 2.0);
880 Eigen::VectorXf jointDesiredTorques = jacobi.transpose() * filteredFTCommand +
881 (I - jacobi.transpose() * jtpinv) * nullspaceTorque;
887 for (
size_t i = 0; i < targets.size(); ++i)
889 targets.at(i)->torque = jointDesiredTorques(i);
891 if (!targets.at(i)->isValid())
893 targets.at(i)->torque = 0.0f;
897 if (fabs(targets.at(i)->torque) > fabs(cfg->maxJointTorque))
899 targets.at(i)->torque = fabs(cfg->maxJointTorque) *
900 (targets.at(i)->torque / fabs(targets.at(i)->torque));
908 tcp->getRobot()->getRootNode()->toGlobalCoordinateSystemVec(currentToolDir);
911 tcp->getRobot()->getRootNode()->toGlobalCoordinateSystem(targetPose);
913 debugRT.
getWriteBuffer().filteredForceInRoot = filteredForceInRoot;
917 tcp->getRobot()->getRootNode()->toGlobalCoordinateSystemVec(filteredForceInRoot);
932 debugRT.
getWriteBuffer().loseContactForceIntegral = forceIntegral;
947 const Ice::StringSeq& fileNames,
953 dmpCtrl->learnDMPFromFiles(fileNames);
958 const TrajectoryBasePtr& trajectory,
963 TrajectoryPtr dmpTraj = TrajectoryPtr::dynamicCast(trajectory);
967 dmpCtrl->learnDMPFromTrajectory(dmpTraj);
974 dmpCtrl->setSpeed(times);
979 const Ice::Current& ice)
982 dmpCtrl->setGoalPoseVec(goals);
990 dmpCtrl->setAmplitude(amp);
1005 const Ice::Current&)
1009 cfg->waitTimeForCalibration)
1018 dmpCtrl->prepareExecution(dmpCtrl->eigen4f2vec(pose), goals);
1019 dmpCtrl->setSpeed(tau);
1028 const Ice::Current&)
1030 abnormalFlag = abnormal;
1038 std::vector<float> tvelvec = {
1039 tvel(0), tvel(1), tvel(2), tpos(0, 3) / 1000, tpos(1, 3) / 1000, tpos(2, 3) / 1000};
1047 std::vector<float> forceVec = {force(0), force(1), force(2)};
1057 std::string datafieldName;
1058 std::string debugName =
"Periodic";
1062 datafields[
"target_x"] =
new Variant(targetPoseDebug(0, 3));
1063 datafields[
"target_y"] =
new Variant(targetPoseDebug(1, 3));
1064 datafields[
"target_z"] =
new Variant(targetPoseDebug(2, 3));
1067 VirtualRobot::MathTools::eigen4f2quat(targetPoseDebug);
1068 datafields[
"target_qw"] =
new Variant(qtarget.w);
1069 datafields[
"target_qx"] =
new Variant(qtarget.x);
1070 datafields[
"target_qy"] =
new Variant(qtarget.y);
1071 datafields[
"target_qz"] =
new Variant(qtarget.z);
1075 datafields[
"current_x"] =
new Variant(currentPoseDebug(0, 3));
1076 datafields[
"current_y"] =
new Variant(currentPoseDebug(1, 3));
1077 datafields[
"current_z"] =
new Variant(currentPoseDebug(2, 3));
1081 VirtualRobot::MathTools::eigen4f2quat(currentPoseDebug);
1082 datafields[
"current_qw"] =
new Variant(qcurrent.w);
1083 datafields[
"current_qx"] =
new Variant(qcurrent.x);
1084 datafields[
"current_qy"] =
new Variant(qcurrent.y);
1085 datafields[
"current_qz"] =
new Variant(qcurrent.z);
1089 datafields[
"filteredforceInTool_x"] =
new Variant(filteredForce(0));
1090 datafields[
"filteredforceInTool_y"] =
new Variant(filteredForce(1));
1091 datafields[
"filteredforceInTool_z"] =
new Variant(filteredForce(2));
1094 datafields[
"filteredtorqueInTool_x"] =
new Variant(filteredTorque(0));
1095 datafields[
"filteredtorqueInTool_y"] =
new Variant(filteredTorque(1));
1096 datafields[
"filteredtorqueInTool_z"] =
new Variant(filteredTorque(2));
1100 datafields[
"filteredForceInRoot_x"] =
new Variant(filteredForceInRoot(0));
1101 datafields[
"filteredForceInRoot_y"] =
new Variant(filteredForceInRoot(1));
1102 datafields[
"filteredForceInRoot_z"] =
new Variant(filteredForceInRoot(2));
1105 datafields[
"rotationAxis_x"] =
new Variant(rotationAxis(0));
1106 datafields[
"rotationAxis_y"] =
new Variant(rotationAxis(1));
1107 datafields[
"rotationAxis_z"] =
new Variant(rotationAxis(2));
1110 datafields[
"reactForce_x"] =
new Variant(reactForce(0));
1111 datafields[
"reactForce_y"] =
new Variant(reactForce(1));
1112 datafields[
"reactForce_z"] =
new Variant(reactForce(2));
1115 datafields[
"targetVel_x"] =
new Variant(targetVel(0));
1116 datafields[
"targetVel_y"] =
new Variant(targetVel(1));
1117 datafields[
"targetVel_z"] =
new Variant(targetVel(2));
1118 datafields[
"targetVel_ro"] =
new Variant(targetVel(3));
1119 datafields[
"targetVel_pi"] =
new Variant(targetVel(4));
1120 datafields[
"targetVel_ya"] =
new Variant(targetVel(5));
1123 datafields[
"currentTwist_x"] =
new Variant(currentTwist(0));
1124 datafields[
"currentTwist_y"] =
new Variant(currentTwist(1));
1125 datafields[
"currentTwist_z"] =
new Variant(currentTwist(2));
1126 datafields[
"currentTwist_ro"] =
new Variant(currentTwist(3));
1127 datafields[
"currentTwist_pi"] =
new Variant(currentTwist(4));
1128 datafields[
"currentTwist_ya"] =
new Variant(currentTwist(5));
1132 datafields[
"adaptK_x"] =
new Variant(adaptK(0));
1133 datafields[
"adaptK_y"] =
new Variant(adaptK(1));
1134 datafields[
"adaptK_z"] =
new Variant(adaptK(2));
1137 datafields[
"adaptD_x"] =
new Variant(adaptD(0));
1138 datafields[
"adaptD_y"] =
new Variant(adaptD(1));
1139 datafields[
"adaptD_z"] =
new Variant(adaptD(2));
1148 datafields[
"loseContactForceIntegral"] =
1152 datafields[
"estimatedFriction_x"] =
new Variant(estFri(0));
1153 datafields[
"estimatedFriction_y"] =
new Variant(estFri(1));
1156 datafields[
"frictionInToolXY_x"] =
new Variant(frictionInToolXY(0));
1157 datafields[
"frictionInToolXY_y"] =
new Variant(frictionInToolXY(1));
1160 datafields[
"velPInTool_x"] =
new Variant(velPInTool(0));
1161 datafields[
"velPInTool_y"] =
new Variant(velPInTool(1));
1162 datafields[
"velPInTool_z"] =
new Variant(velPInTool(2));
1198 datafieldName =
"PeriodicDMP";
1199 debugObs->setDebugChannel(datafieldName, datafields);
1204 Eigen::Vector3f handPosition = globalPose.block<3, 1>(0, 3);
1207 debugDrawer->setArrowVisu(
"Force",
1211 DrawColor{0, 0, 1, 1},
1212 10 * forceDir.norm(),
1217 debugDrawer->setArrowVisu(
"Tool",
1221 DrawColor{1, 0, 0, 1},
1224 debugDrawer->setPoseVisu(
"target",
"targetPose",
new Pose(globalPose));
1230 dmpCtrl->pauseController();
1236 dmpCtrl->resumeController();