3 #include <VirtualRobot/IK/DifferentialIK.h>
4 #include <VirtualRobot/MathTools.h>
5 #include <VirtualRobot/Nodes/RobotNode.h>
6 #include <VirtualRobot/Nodes/Sensor.h>
7 #include <VirtualRobot/Robot.h>
8 #include <VirtualRobot/RobotNodeSet.h>
20 #include <dmp/representation/dmp/umitsmp.h>
24 NJointControllerRegistration<DeprecatedNJointTaskSpaceImpedanceDMPController>
26 "DeprecatedNJointTaskSpaceImpedanceDMPController");
31 const armarx::NJointControllerConfigPtr& config,
36 cfg = DeprecatedNJointTaskSpaceImpedanceDMPControllerConfigPtr::dynamicCast(config);
39 rns =
rtGetRobot()->getRobotNodeSet(cfg->nodeSetName);
42 for (
size_t i = 0; i < rns->getSize(); ++i)
44 std::string jointName = rns->getNode(i)->getName();
45 jointNames.push_back(jointName);
48 targets.push_back(ct->
asA<ControlTarget1DoFActuatorTorque>());
49 const SensorValue1DoFActuatorVelocity* velocitySensor =
50 sv->
asA<SensorValue1DoFActuatorVelocity>();
51 const SensorValue1DoFActuatorPosition* positionSensor =
52 sv->
asA<SensorValue1DoFActuatorPosition>();
63 velocitySensors.push_back(velocitySensor);
64 positionSensors.push_back(positionSensor);
67 robotUnit->getSensorDevice(cfg->forceSensorName)->getSensorValue();
71 forceOffset.setZero();
72 filteredForce.setZero();
73 filteredForceInRoot.setZero();
77 ik.reset(
new VirtualRobot::DifferentialIK(
78 rns,
rtGetRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
79 ik->setDampedSvdLambda(0.0001);
82 numOfJoints = targets.size();
87 taskSpaceDMPConfig.
DMPMode = cfg->dmpMode;
88 taskSpaceDMPConfig.
DMPStyle = cfg->dmpType;
104 useNullSpaceJointDMP = cfg->useNullSpaceJointDMP;
105 nullSpaceJointDMPPtr.reset(
new DMP::UMIDMP(100));
107 isNullSpaceJointDMPLearned =
false;
109 Eigen::VectorXf nullspaceValues(targets.size());
113 for (
size_t i = 0; i < targets.size(); ++i)
115 nullspaceValues(i) = cfg->defaultNullSpaceJointValues.at(i);
120 Eigen::Vector3f kpos(cfg->Kpos[0], cfg->Kpos[1], cfg->Kpos[2]);
121 Eigen::Vector3f dpos(cfg->Dpos[0], cfg->Dpos[1], cfg->Dpos[2]);
122 Eigen::Vector3f kori(cfg->Kori[0], cfg->Kori[1], cfg->Kori[2]);
123 Eigen::Vector3f dori(cfg->Dori[0], cfg->Dori[1], cfg->Dori[2]);
124 Eigen::VectorXf knull(targets.size());
125 Eigen::VectorXf dnull(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 CtrlParams initParams = {kpos, dpos, kori, dori, knull, dnull};
139 torqueLimit = cfg->torqueLimit;
140 timeDuration = cfg->timeDuration;
142 DeprecatedNJointTaskSpaceImpedanceDMPControllerInterfaceData initInterfaceData;
146 DeprecatedNJointTaskSpaceImpedanceDMPControllerSensorData initControllerSensorData;
148 initControllerSensorData.currentTime = 0;
149 initControllerSensorData.deltaT = 0;
150 initControllerSensorData.currentTwist.setZero();
154 useForceStop =
false;
162 return "DeprecatedNJointTaskSpaceImpedanceDMPController";
170 initData.
targetPose = tcp->getPoseInRootFrame();
191 double deltaT = 0.001;
193 Eigen::VectorXf currentTwist = controllerSensorData.
getReadBuffer().currentTwist;
222 if (dmpCtrl->canVal < 1e-8)
232 dmpCtrl->flow(deltaT, currentPose, currentTwist);
234 Eigen::VectorXf desiredNullSpaceJointValues(jointNames.size());
235 if (useNullSpaceJointDMP && isNullSpaceJointDMPLearned)
238 currentJointState = nullSpaceJointDMPPtr->calculateDirectlyVelocity(
240 dmpCtrl->canVal / timeDuration,
241 deltaT / timeDuration,
244 if (targetJointState.size() == jointNames.size())
246 for (
size_t i = 0; i < targetJointState.size(); ++i)
248 desiredNullSpaceJointValues(i) = targetJointState[i];
253 desiredNullSpaceJointValues =
259 desiredNullSpaceJointValues =
283 double deltaT = timeSinceLastIteration.toSecondsDouble();
285 Eigen::VectorXf targetVel;
286 Eigen::VectorXf desiredNullSpaceJointValues;
291 targetPose = currentPose;
292 stopPose = currentPose;
293 targetVel.setZero(6);
300 targetPose = stopPose;
301 targetVel.setZero(6);
304 (1 - cfg->forceFilter) * forceOffset + cfg->forceFilter * forceSensor->
force;
305 timeForCalibration = timeForCalibration + timeSinceLastIteration.toSecondsDouble();
312 stopPose = targetPose;
317 filteredForce = (1 - cfg->forceFilter) * filteredForce +
318 cfg->forceFilter * (forceSensor->
force - forceOffset);
320 for (
size_t i = 0; i < 3; ++i)
322 if (fabs(filteredForce(i)) > cfg->forceDeadZone)
325 (filteredForce(i) / fabs(filteredForce(i))) * cfg->forceDeadZone;
329 filteredForce(i) = 0;
333 ->getSensor(cfg->forceSensorName)
335 ->getPoseInRootFrame();
336 filteredForceInRoot = forceFrameInRoot.block<3, 3>(0, 0) * filteredForce;
338 for (
size_t i = 0; i < 3; ++i)
340 if (fabs(filteredForceInRoot[i]) >
343 stopPose = currentPose;
344 targetVel.setZero(6);
345 desiredNullSpaceJointValues =
356 Eigen::MatrixXf jacobi =
357 ik->getJacobianMatrix(tcp, VirtualRobot::IKSolver::CartesianSelection::All);
359 Eigen::VectorXf qpos(positionSensors.size());
360 Eigen::VectorXf qvel(velocitySensors.size());
361 for (
size_t i = 0; i < positionSensors.size(); ++i)
363 qpos(i) = positionSensors[i]->position;
364 qvel(i) = velocitySensors[i]->velocity;
367 Eigen::VectorXf currentTwist = jacobi * qvel;
370 controllerSensorData.
getWriteBuffer().currentTwist = currentTwist;
378 jacobi.block(0, 0, 3, numOfJoints) =
379 0.001 * jacobi.block(0, 0, 3, numOfJoints);
390 Eigen::Vector3f targetTCPLinearVelocity;
391 targetTCPLinearVelocity << 0.001 * targetVel(0), 0.001 * targetVel(1),
392 0.001 * targetVel(2);
393 Eigen::Vector3f currentTCPLinearVelocity;
394 currentTCPLinearVelocity << 0.001 * currentTwist(0), 0.001 * currentTwist(1),
395 0.001 * currentTwist(2);
396 Eigen::Vector3f currentTCPPosition = currentPose.block<3, 1>(0, 3);
397 Eigen::Vector3f desiredPosition = targetPose.block<3, 1>(0, 3);
398 Eigen::Vector3f tcpDesiredForce =
399 0.001 * kpos.cwiseProduct(desiredPosition - currentTCPPosition) +
400 dpos.cwiseProduct(targetTCPLinearVelocity - currentTCPLinearVelocity);
402 Eigen::Vector3f currentTCPAngularVelocity;
403 currentTCPAngularVelocity << currentTwist(3), currentTwist(4), currentTwist(5);
405 Eigen::Matrix3f diffMat = targetPose.block<3, 3>(0, 0) * currentRotMat.inverse();
406 Eigen::Vector3f rpy = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
407 Eigen::Vector3f tcpDesiredTorque =
408 kori.cwiseProduct(rpy) - dori.cwiseProduct(currentTCPAngularVelocity);
409 jointControlWrench << tcpDesiredForce, tcpDesiredTorque;
414 Eigen::VectorXf nullspaceTorque =
415 knull.cwiseProduct(desiredNullSpaceJointValues - qpos) - dnull.cwiseProduct(qvel);
416 Eigen::MatrixXf jtpinv = ik->computePseudoInverseJacobianMatrix(jacobi.transpose(), 2.0);
417 Eigen::VectorXf jointDesiredTorques = jacobi.transpose() * jointControlWrench +
418 (I - jacobi.transpose() * jtpinv) * nullspaceTorque;
424 for (
size_t i = 0; i < targets.size(); ++i)
426 float desiredTorque = jointDesiredTorques(i);
428 if (isnan(desiredTorque))
433 desiredTorque = (desiredTorque > torqueLimit) ? torqueLimit : desiredTorque;
434 desiredTorque = (desiredTorque < -torqueLimit) ? -torqueLimit : desiredTorque;
437 jointDesiredTorques(i);
438 debugOutputData.
getWriteBuffer().desired_nullspaceJoint[jointNames[i]] =
439 desiredNullSpaceJointValues(i);
441 targets.at(i)->torque = desiredTorque;
442 if (!targets.at(i)->isValid())
445 <<
"Torque controller target is invalid - setting to zero! set value: "
446 << targets.at(i)->torque;
447 targets.at(i)->torque = 0.0f;
452 debugOutputData.
getWriteBuffer().forceDesired_x = jointControlWrench(0);
453 debugOutputData.
getWriteBuffer().forceDesired_y = jointControlWrench(1);
454 debugOutputData.
getWriteBuffer().forceDesired_z = jointControlWrench(2);
455 debugOutputData.
getWriteBuffer().forceDesired_rx = jointControlWrench(3);
456 debugOutputData.
getWriteBuffer().forceDesired_ry = jointControlWrench(4);
457 debugOutputData.
getWriteBuffer().forceDesired_rz = jointControlWrench(5);
466 VirtualRobot::MathTools::eigen4f2quat(targetPose);
473 debugOutputData.
getWriteBuffer().currentPose_x = currentPose(0, 3);
474 debugOutputData.
getWriteBuffer().currentPose_y = currentPose(1, 3);
475 debugOutputData.
getWriteBuffer().currentPose_z = currentPose(2, 3);
477 VirtualRobot::MathTools::eigen4f2quat(currentPose);
504 debugOutputData.
getWriteBuffer().filteredForceInRoot = filteredForceInRoot;
511 const Ice::StringSeq& fileNames,
514 dmpCtrl->learnDMPFromFiles(fileNames);
520 const Ice::DoubleSeq& viapoint,
525 dmpCtrl->setViaPose(u, viapoint);
530 const Ice::Current& ice)
532 dmpCtrl->setGoalPoseVec(goals);
537 const std::string& fileName,
538 const Ice::FloatSeq& currentJVS,
541 DMP::Vec<DMP::SampledTrajectoryV2> trajs;
543 DMP::SampledTrajectoryV2 traj;
544 traj.readFromCSVFile(fileName);
546 if (traj.dim() != jointNames.size())
548 isNullSpaceJointDMPLearned =
false;
553 goal.resize(traj.dim());
554 currentJointState.resize(traj.dim());
556 for (
size_t i = 0; i < goal.size(); ++i)
558 goal.at(i) = traj.rbegin()->getPosition(i);
559 currentJointState.at(i).pos = currentJVS.at(i);
560 currentJointState.at(i).vel = 0;
563 trajs.push_back(traj);
564 nullSpaceJointDMPPtr->learnFromTrajectories(trajs);
567 nullSpaceJointDMPPtr->prepareExecution(goal, currentJointState, 1.0, 1.0);
569 isNullSpaceJointDMPLearned =
true;
594 return dmpCtrl->saveDMPToString();
599 const std::string& dmpString,
602 dmpCtrl->loadDMPFromString(dmpString);
603 return dmpCtrl->dmpPtr->defaultGoal;
609 return dmpCtrl->canVal;
622 useNullSpaceJointDMP = enable;
630 dmpCtrl->canVal = timeDuration;
631 dmpCtrl->config.motionTimeDuration = timeDuration;
641 timeForCalibration = 0;
644 while (firstRun || timeForCalibration < cfg->waitTimeForCalibration)
661 dmpCtrl->prepareExecution(dmpCtrl->eigen4f2vec(pose), goals);
664 if (isNullSpaceJointDMPLearned && useNullSpaceJointDMP)
684 datafields[
"torqueDesired_" + pair.first] =
new Variant(pair.second);
688 for (
auto& pair : values_null)
690 datafields[
"nullspaceDesired_" + pair.first] =
new Variant(pair.second);
695 datafields[
"targetPose_x"] =
697 datafields[
"targetPose_y"] =
699 datafields[
"targetPose_z"] =
701 datafields[
"targetPose_qw"] =
703 datafields[
"targetPose_qx"] =
705 datafields[
"targetPose_qy"] =
707 datafields[
"targetPose_qz"] =
710 datafields[
"currentPose_x"] =
712 datafields[
"currentPose_y"] =
714 datafields[
"currentPose_z"] =
716 datafields[
"currentPose_qw"] =
718 datafields[
"currentPose_qx"] =
720 datafields[
"currentPose_qy"] =
722 datafields[
"currentPose_qz"] =
725 datafields[
"currentKpos_x"] =
727 datafields[
"currentKpos_y"] =
729 datafields[
"currentKpos_z"] =
731 datafields[
"currentKori_x"] =
733 datafields[
"currentKori_y"] =
735 datafields[
"currentKori_z"] =
737 datafields[
"currentKnull_x"] =
739 datafields[
"currentKnull_y"] =
741 datafields[
"currentKnull_z"] =
744 datafields[
"currentDpos_x"] =
746 datafields[
"currentDpos_y"] =
748 datafields[
"currentDpos_z"] =
750 datafields[
"currentDori_x"] =
752 datafields[
"currentDori_y"] =
754 datafields[
"currentDori_z"] =
756 datafields[
"currentDnull_x"] =
758 datafields[
"currentDnull_y"] =
760 datafields[
"currentDnull_z"] =
763 datafields[
"forceDesired_x"] =
765 datafields[
"forceDesired_y"] =
767 datafields[
"forceDesired_z"] =
769 datafields[
"forceDesired_rx"] =
771 datafields[
"forceDesired_ry"] =
773 datafields[
"forceDesired_rz"] =
776 datafields[
"filteredForceInRoot_x"] =
778 datafields[
"filteredForceInRoot_y"] =
780 datafields[
"filteredForceInRoot_z"] =
785 std::string channelName = cfg->nodeSetName +
"_TaskSpaceImpedanceControl";
786 debugObs->setDebugChannel(channelName, datafields);
794 runTask(
"DeprecatedNJointTaskSpaceImpedanceDMPController",
799 while (
getState() == eManagedIceObjectStarted)
805 c.waitForCycleDuration();
820 dmpCtrl->setWeights(weights);
826 DMP::DVec2d res = dmpCtrl->getWeights();
828 for (
size_t i = 0; i < res.size(); ++i)
830 std::vector<double> cvec;
831 for (
size_t j = 0; j < res[i].size(); ++j)
833 cvec.push_back(res[i][j]);
835 resvec.push_back(cvec);
846 dmpCtrl->removeAllViaPoints();
895 const Eigen::VectorXf& kd,
907 const Eigen::VectorXf& kp,
919 const Eigen::VectorXf& jointValues,