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();
75 forceThreshold.reinitAllBuffers(cfg->forceThreshold);
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);
117 defaultNullSpaceJointValues.reinitAllBuffers(nullspaceValues);
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};
137 ctrlParams.reinitAllBuffers(initParams);
139 torqueLimit = cfg->torqueLimit;
140 timeDuration = cfg->timeDuration;
142 DeprecatedNJointTaskSpaceImpedanceDMPControllerInterfaceData initInterfaceData;
143 initInterfaceData.currentTcpPose = Eigen::Matrix4f::Identity();
144 interfaceData.reinitAllBuffers(initInterfaceData);
146 DeprecatedNJointTaskSpaceImpedanceDMPControllerSensorData initControllerSensorData;
147 initControllerSensorData.currentPose = Eigen::Matrix4f::Identity();
148 initControllerSensorData.currentTime = 0;
149 initControllerSensorData.deltaT = 0;
150 initControllerSensorData.currentTwist.setZero();
151 controllerSensorData.reinitAllBuffers(initControllerSensorData);
154 useForceStop =
false;
277 const IceUtil::Time& sensorValuesTimestamp,
278 const IceUtil::Time& timeSinceLastIteration)
281 Eigen::Matrix4f currentPose = tcp->getPoseInRootFrame();
283 double deltaT = timeSinceLastIteration.toSecondsDouble();
284 Eigen::Matrix4f targetPose;
285 Eigen::VectorXf targetVel;
286 Eigen::VectorXf desiredNullSpaceJointValues;
291 targetPose = currentPose;
292 stopPose = currentPose;
293 targetVel.setZero(6);
294 desiredNullSpaceJointValues = defaultNullSpaceJointValues.getUpToDateReadBuffer();
300 targetPose = stopPose;
301 targetVel.setZero(6);
302 desiredNullSpaceJointValues = defaultNullSpaceJointValues.getUpToDateReadBuffer();
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;
332 Eigen::Matrix4f forceFrameInRoot =
rtGetRobot()
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]) >
341 forceThreshold.getUpToDateReadBuffer()[i])
343 stopPose = currentPose;
344 targetVel.setZero(6);
345 desiredNullSpaceJointValues =
346 defaultNullSpaceJointValues.getUpToDateReadBuffer();
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;
369 controllerSensorData.getWriteBuffer().currentPose = currentPose;
370 controllerSensorData.getWriteBuffer().currentTwist = currentTwist;
371 controllerSensorData.getWriteBuffer().deltaT = deltaT;
372 controllerSensorData.getWriteBuffer().currentTime += deltaT;
373 controllerSensorData.commitWrite();
375 interfaceData.getWriteBuffer().currentTcpPose = currentPose;
376 interfaceData.commitWrite();
378 jacobi.block(0, 0, 3, numOfJoints) =
379 0.001 * jacobi.block(0, 0, 3, numOfJoints);
381 Eigen::Vector3f kpos = ctrlParams.getUpToDateReadBuffer().kpos;
382 Eigen::Vector3f dpos = ctrlParams.getUpToDateReadBuffer().dpos;
383 Eigen::Vector3f kori = ctrlParams.getUpToDateReadBuffer().kori;
384 Eigen::Vector3f dori = ctrlParams.getUpToDateReadBuffer().dori;
385 Eigen::VectorXf knull = ctrlParams.getUpToDateReadBuffer().knull;
386 Eigen::VectorXf dnull = ctrlParams.getUpToDateReadBuffer().dnull;
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);
404 Eigen::Matrix3f currentRotMat = currentPose.block<3, 3>(0, 0);
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;
412 Eigen::MatrixXf I = Eigen::MatrixXf::Identity(targets.size(), targets.size());
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;
436 debugOutputData.getWriteBuffer().desired_torques[jointNames[i]] =
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);
462 debugOutputData.getWriteBuffer().targetPose_x = targetPose(0, 3);
463 debugOutputData.getWriteBuffer().targetPose_y = targetPose(1, 3);
464 debugOutputData.getWriteBuffer().targetPose_z = targetPose(2, 3);
465 VirtualRobot::MathTools::Quaternion targetQuat =
466 VirtualRobot::MathTools::eigen4f2quat(targetPose);
467 debugOutputData.getWriteBuffer().targetPose_qw = targetQuat.w;
468 debugOutputData.getWriteBuffer().targetPose_qx = targetQuat.x;
469 debugOutputData.getWriteBuffer().targetPose_qy = targetQuat.y;
470 debugOutputData.getWriteBuffer().targetPose_qz = targetQuat.z;
473 debugOutputData.getWriteBuffer().currentPose_x = currentPose(0, 3);
474 debugOutputData.getWriteBuffer().currentPose_y = currentPose(1, 3);
475 debugOutputData.getWriteBuffer().currentPose_z = currentPose(2, 3);
476 VirtualRobot::MathTools::Quaternion currentQuat =
477 VirtualRobot::MathTools::eigen4f2quat(currentPose);
478 debugOutputData.getWriteBuffer().currentPose_qw = currentQuat.w;
479 debugOutputData.getWriteBuffer().currentPose_qx = currentQuat.x;
480 debugOutputData.getWriteBuffer().currentPose_qy = currentQuat.y;
481 debugOutputData.getWriteBuffer().currentPose_qz = currentQuat.z;
482 debugOutputData.getWriteBuffer().deltaT = deltaT;
484 debugOutputData.getWriteBuffer().currentKpos_x = kpos.x();
485 debugOutputData.getWriteBuffer().currentKpos_y = kpos.y();
486 debugOutputData.getWriteBuffer().currentKpos_z = kpos.z();
487 debugOutputData.getWriteBuffer().currentKori_x = kori.x();
488 debugOutputData.getWriteBuffer().currentKori_y = kori.y();
489 debugOutputData.getWriteBuffer().currentKori_z = kori.z();
490 debugOutputData.getWriteBuffer().currentKnull_x = knull.x();
491 debugOutputData.getWriteBuffer().currentKnull_y = knull.y();
492 debugOutputData.getWriteBuffer().currentKnull_z = knull.z();
494 debugOutputData.getWriteBuffer().currentDpos_x = dpos.x();
495 debugOutputData.getWriteBuffer().currentDpos_y = dpos.y();
496 debugOutputData.getWriteBuffer().currentDpos_z = dpos.z();
497 debugOutputData.getWriteBuffer().currentDori_x = dori.x();
498 debugOutputData.getWriteBuffer().currentDori_y = dori.y();
499 debugOutputData.getWriteBuffer().currentDori_z = dori.z();
500 debugOutputData.getWriteBuffer().currentDnull_x = dnull.x();
501 debugOutputData.getWriteBuffer().currentDnull_y = dnull.y();
502 debugOutputData.getWriteBuffer().currentDnull_z = dnull.z();
504 debugOutputData.getWriteBuffer().filteredForceInRoot = filteredForceInRoot;
506 debugOutputData.commitWrite();
681 auto values = debugOutputData.getUpToDateReadBuffer().desired_torques;
682 for (
auto& pair : values)
684 datafields[
"torqueDesired_" + pair.first] =
new Variant(pair.second);
687 auto values_null = debugOutputData.getUpToDateReadBuffer().desired_nullspaceJoint;
688 for (
auto& pair : values_null)
690 datafields[
"nullspaceDesired_" + pair.first] =
new Variant(pair.second);
693 datafields[
"canVal"] =
new Variant(debugOutputData.getUpToDateReadBuffer().currentCanVal);
694 datafields[
"mpcfactor"] =
new Variant(debugOutputData.getUpToDateReadBuffer().mpcfactor);
695 datafields[
"targetPose_x"] =
696 new Variant(debugOutputData.getUpToDateReadBuffer().targetPose_x);
697 datafields[
"targetPose_y"] =
698 new Variant(debugOutputData.getUpToDateReadBuffer().targetPose_y);
699 datafields[
"targetPose_z"] =
700 new Variant(debugOutputData.getUpToDateReadBuffer().targetPose_z);
701 datafields[
"targetPose_qw"] =
702 new Variant(debugOutputData.getUpToDateReadBuffer().targetPose_qw);
703 datafields[
"targetPose_qx"] =
704 new Variant(debugOutputData.getUpToDateReadBuffer().targetPose_qx);
705 datafields[
"targetPose_qy"] =
706 new Variant(debugOutputData.getUpToDateReadBuffer().targetPose_qy);
707 datafields[
"targetPose_qz"] =
708 new Variant(debugOutputData.getUpToDateReadBuffer().targetPose_qz);
710 datafields[
"currentPose_x"] =
711 new Variant(debugOutputData.getUpToDateReadBuffer().currentPose_x);
712 datafields[
"currentPose_y"] =
713 new Variant(debugOutputData.getUpToDateReadBuffer().currentPose_y);
714 datafields[
"currentPose_z"] =
715 new Variant(debugOutputData.getUpToDateReadBuffer().currentPose_z);
716 datafields[
"currentPose_qw"] =
717 new Variant(debugOutputData.getUpToDateReadBuffer().currentPose_qw);
718 datafields[
"currentPose_qx"] =
719 new Variant(debugOutputData.getUpToDateReadBuffer().currentPose_qx);
720 datafields[
"currentPose_qy"] =
721 new Variant(debugOutputData.getUpToDateReadBuffer().currentPose_qy);
722 datafields[
"currentPose_qz"] =
723 new Variant(debugOutputData.getUpToDateReadBuffer().currentPose_qz);
725 datafields[
"currentKpos_x"] =
726 new Variant(debugOutputData.getUpToDateReadBuffer().currentKpos_x);
727 datafields[
"currentKpos_y"] =
728 new Variant(debugOutputData.getUpToDateReadBuffer().currentKpos_y);
729 datafields[
"currentKpos_z"] =
730 new Variant(debugOutputData.getUpToDateReadBuffer().currentKpos_z);
731 datafields[
"currentKori_x"] =
732 new Variant(debugOutputData.getUpToDateReadBuffer().currentKori_x);
733 datafields[
"currentKori_y"] =
734 new Variant(debugOutputData.getUpToDateReadBuffer().currentKori_y);
735 datafields[
"currentKori_z"] =
736 new Variant(debugOutputData.getUpToDateReadBuffer().currentKori_z);
737 datafields[
"currentKnull_x"] =
738 new Variant(debugOutputData.getUpToDateReadBuffer().currentKnull_x);
739 datafields[
"currentKnull_y"] =
740 new Variant(debugOutputData.getUpToDateReadBuffer().currentKnull_y);
741 datafields[
"currentKnull_z"] =
742 new Variant(debugOutputData.getUpToDateReadBuffer().currentKnull_z);
744 datafields[
"currentDpos_x"] =
745 new Variant(debugOutputData.getUpToDateReadBuffer().currentDpos_x);
746 datafields[
"currentDpos_y"] =
747 new Variant(debugOutputData.getUpToDateReadBuffer().currentDpos_y);
748 datafields[
"currentDpos_z"] =
749 new Variant(debugOutputData.getUpToDateReadBuffer().currentDpos_z);
750 datafields[
"currentDori_x"] =
751 new Variant(debugOutputData.getUpToDateReadBuffer().currentDori_x);
752 datafields[
"currentDori_y"] =
753 new Variant(debugOutputData.getUpToDateReadBuffer().currentDori_y);
754 datafields[
"currentDori_z"] =
755 new Variant(debugOutputData.getUpToDateReadBuffer().currentDori_z);
756 datafields[
"currentDnull_x"] =
757 new Variant(debugOutputData.getUpToDateReadBuffer().currentDnull_x);
758 datafields[
"currentDnull_y"] =
759 new Variant(debugOutputData.getUpToDateReadBuffer().currentDnull_y);
760 datafields[
"currentDnull_z"] =
761 new Variant(debugOutputData.getUpToDateReadBuffer().currentDnull_z);
763 datafields[
"forceDesired_x"] =
764 new Variant(debugOutputData.getUpToDateReadBuffer().forceDesired_x);
765 datafields[
"forceDesired_y"] =
766 new Variant(debugOutputData.getUpToDateReadBuffer().forceDesired_y);
767 datafields[
"forceDesired_z"] =
768 new Variant(debugOutputData.getUpToDateReadBuffer().forceDesired_z);
769 datafields[
"forceDesired_rx"] =
770 new Variant(debugOutputData.getUpToDateReadBuffer().forceDesired_rx);
771 datafields[
"forceDesired_ry"] =
772 new Variant(debugOutputData.getUpToDateReadBuffer().forceDesired_ry);
773 datafields[
"forceDesired_rz"] =
774 new Variant(debugOutputData.getUpToDateReadBuffer().forceDesired_rz);
776 datafields[
"filteredForceInRoot_x"] =
777 new Variant(debugOutputData.getUpToDateReadBuffer().filteredForceInRoot[0]);
778 datafields[
"filteredForceInRoot_y"] =
779 new Variant(debugOutputData.getUpToDateReadBuffer().filteredForceInRoot[1]);
780 datafields[
"filteredForceInRoot_z"] =
781 new Variant(debugOutputData.getUpToDateReadBuffer().filteredForceInRoot[2]);
783 datafields[
"deltaT"] =
new Variant(debugOutputData.getUpToDateReadBuffer().deltaT);
785 std::string channelName = cfg->nodeSetName +
"_TaskSpaceImpedanceControl";
786 debugObs->setDebugChannel(channelName, datafields);