30 const armarx::NJointControllerConfigPtr& config,
34 cfg = NJointTaskSpaceAdaptiveDMPControllerConfigPtr::dynamicCast(config);
36 rns =
rtGetRobot()->getRobotNodeSet(cfg->nodeSetName);
39 for (
size_t i = 0; i < rns->getSize(); ++i)
41 std::string jointName = rns->getNode(i)->getName();
42 jointNames.push_back(jointName);
45 targets.push_back(ct->
asA<ControlTarget1DoFActuatorTorque>());
46 const SensorValue1DoFActuatorVelocity* velocitySensor =
47 sv->
asA<SensorValue1DoFActuatorVelocity>();
48 const SensorValue1DoFActuatorPosition* positionSensor =
49 sv->
asA<SensorValue1DoFActuatorPosition>();
60 velocitySensors.push_back(velocitySensor);
61 positionSensors.push_back(positionSensor);
66 robotUnit->getSensorDevice(cfg->forceSensorName)->getSensorValue();
70 ik.reset(
new VirtualRobot::DifferentialIK(
71 rns,
rtGetRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
72 numOfJoints = targets.size();
76 double phaseDist0 = 10000;
77 double phaseDist1 = 10000;
78 double posToOriRatio = 10;
83 taskSpaceDMPConfig.
DMPMode = cfg->dmpMode;
84 taskSpaceDMPConfig.
DMPStyle = cfg->dmpType;
100 useNullSpaceJointDMP = cfg->useNullSpaceJointDMP;
101 nullSpaceJointDMPPtr.reset(
new DMP::UMIDMP(100));
103 isNullSpaceJointDMPLearned =
false;
105 defaultNullSpaceJointValues.resize(targets.size());
108 for (
size_t i = 0; i < targets.size(); ++i)
110 defaultNullSpaceJointValues(i) = cfg->defaultNullSpaceJointValues.at(i);
114 kpos << cfg->Kpos[0], cfg->Kpos[1], cfg->Kpos[2];
115 dpos << cfg->Dpos[0], cfg->Dpos[1], cfg->Dpos[2];
116 kori << cfg->Kori[0], cfg->Kori[1], cfg->Kori[2];
117 dori << cfg->Dori[0], cfg->Dori[1], cfg->Dori[2];
123 knull.setZero(targets.size());
124 dnull.setZero(targets.size());
126 for (
size_t i = 0; i < targets.size(); ++i)
128 knull(i) = cfg->Knull.at(i);
129 dnull(i) = cfg->Dnull.at(i);
132 torqueLimit = cfg->torqueLimit;
133 timeDuration = cfg->timeDuration;
135 NJointTaskSpaceAdaptiveDMPControllerInterfaceData initInterfaceData;
136 initInterfaceData.currentTcpPose = Eigen::Matrix4f::Identity();
137 initInterfaceData.currentForce = Eigen::Vector3f::Zero();
138 initInterfaceData.currentVel.setZero(6);
139 interfaceData.reinitAllBuffers(initInterfaceData);
141 NJointTaskSpaceAdaptiveDMPControllerSensorData initControllerSensorData;
142 initControllerSensorData.currentPose = Eigen::Matrix4f::Identity();
143 initControllerSensorData.currentTime = 0;
144 initControllerSensorData.deltaT = 0;
145 initControllerSensorData.currentTwist.setZero();
146 controllerSensorData.reinitAllBuffers(initControllerSensorData);
149 Eigen::VectorXf KpImpedance;
150 KpImpedance.setZero(6);
152 for (
int i = 0; i < 3; ++i)
154 KpImpedance(i) = cfg->Kpos.at(i);
155 KpImpedance(i + 3) = cfg->Kori.at(i);
158 Eigen::VectorXf KdImpedance;
159 KdImpedance.setZero(6);
161 for (
int i = 0; i < 3; ++i)
163 KdImpedance(i) = cfg->Dpos.at(i);
164 KdImpedance(i + 3) = cfg->Dori.at(i);
167 Inferface2rtData initInt2rtData;
168 initInt2rtData.KpImpedance = KpImpedance;
169 initInt2rtData.KdImpedance = KdImpedance;
170 initInt2rtData.Knull = knull;
171 initInt2rtData.Dnull = dnull;
172 interface2rtBuffer.reinitAllBuffers(initInt2rtData);
175 Interface2CtrlData initInt2CtrlData;
176 initInt2CtrlData.canVal = 1.0;
177 interface2CtrlBuffer.reinitAllBuffers(initInt2CtrlData);
180 forceOffset.setZero(3);
181 filteredForce.setZero(3);
305 const IceUtil::Time& timeSinceLastIteration)
307 double deltaT = timeSinceLastIteration.toSecondsDouble();
308 Eigen::Matrix4f currentPose = tcp->getPoseInRootFrame();
310 Eigen::MatrixXf jacobi =
311 ik->getJacobianMatrix(tcp, VirtualRobot::IKSolver::CartesianSelection::All);
313 Eigen::VectorXf qpos(positionSensors.size());
314 Eigen::VectorXf qvel(velocitySensors.size());
315 for (
size_t i = 0; i < positionSensors.size(); ++i)
317 qpos(i) = positionSensors[i]->position;
318 qvel(i) = velocitySensors[i]->velocity;
321 Eigen::VectorXf currentTwist = jacobi * qvel;
323 controllerSensorData.getWriteBuffer().currentPose = currentPose;
324 controllerSensorData.getWriteBuffer().currentTwist = currentTwist;
325 controllerSensorData.getWriteBuffer().deltaT = deltaT;
326 controllerSensorData.getWriteBuffer().currentTime += deltaT;
327 controllerSensorData.commitWrite();
330 Eigen::Matrix4f targetPose;
331 Eigen::VectorXf targetVel;
332 Eigen::VectorXf desiredNullSpaceJointValues;
333 if (firstRun || !started)
336 targetPose = currentPose;
337 targetVel.setZero(6);
338 desiredNullSpaceJointValues = defaultNullSpaceJointValues;
339 forceOffset = 0.1 * forceOffset + 0.9 * forceSensor->force;
343 filteredForce = (1 - cfg->filterCoeff) * filteredForce +
344 cfg->filterCoeff * (forceSensor->force - forceOffset);
350 interfaceData.getWriteBuffer().currentTcpPose = currentPose;
351 interfaceData.getWriteBuffer().currentForce = filteredForce;
352 interfaceData.getWriteBuffer().currentVel = currentTwist;
353 interfaceData.commitWrite();
356 kpos = interface2rtBuffer.getUpToDateReadBuffer().KpImpedance.head<3>();
357 kori = interface2rtBuffer.getUpToDateReadBuffer().KpImpedance.tail<3>();
358 dpos = interface2rtBuffer.getUpToDateReadBuffer().KdImpedance.head<3>();
359 dori = interface2rtBuffer.getUpToDateReadBuffer().KdImpedance.tail<3>();
360 knull = interface2rtBuffer.getUpToDateReadBuffer().Knull;
361 dnull = interface2rtBuffer.getUpToDateReadBuffer().Dnull;
364 jacobi.block(0, 0, 3, numOfJoints) =
365 0.001 * jacobi.block(0, 0, 3, numOfJoints);
368 Eigen::Vector3f targetTCPLinearVelocity;
369 targetTCPLinearVelocity << 0.001 * targetVel(0), 0.001 * targetVel(1),
370 0.001 * targetVel(2);
371 Eigen::Vector3f currentTCPLinearVelocity;
372 currentTCPLinearVelocity << 0.001 * currentTwist(0), 0.001 * currentTwist(1),
373 0.001 * currentTwist(2);
374 Eigen::Vector3f currentTCPPosition = currentPose.block<3, 1>(0, 3);
375 Eigen::Vector3f desiredPosition = targetPose.block<3, 1>(0, 3);
376 Eigen::Vector3f tcpDesiredForce =
377 0.001 * kpos.cwiseProduct(desiredPosition - currentTCPPosition) +
378 dpos.cwiseProduct(targetTCPLinearVelocity - currentTCPLinearVelocity);
380 Eigen::Vector3f currentTCPAngularVelocity;
381 currentTCPAngularVelocity << currentTwist(3), currentTwist(4), currentTwist(5);
382 Eigen::Matrix3f currentRotMat = currentPose.block<3, 3>(0, 0);
383 Eigen::Matrix3f diffMat = targetPose.block<3, 3>(0, 0) * currentRotMat.inverse();
384 Eigen::Vector3f rpy = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
385 Eigen::Vector3f tcpDesiredTorque =
386 kori.cwiseProduct(rpy) - dori.cwiseProduct(currentTCPAngularVelocity);
387 jointControlWrench << tcpDesiredForce, tcpDesiredTorque;
390 Eigen::MatrixXf I = Eigen::MatrixXf::Identity(targets.size(), targets.size());
392 Eigen::VectorXf nullspaceTorque =
393 knull.cwiseProduct(desiredNullSpaceJointValues - qpos) - dnull.cwiseProduct(qvel);
394 Eigen::MatrixXf jtpinv = ik->computePseudoInverseJacobianMatrix(jacobi.transpose(), 2.0);
395 Eigen::VectorXf jointDesiredTorques = jacobi.transpose() * jointControlWrench +
396 (I - jacobi.transpose() * jtpinv) * nullspaceTorque;
401 for (
size_t i = 0; i < targets.size(); ++i)
403 float desiredTorque = jointDesiredTorques(i);
405 if (isnan(desiredTorque))
410 desiredTorque = (desiredTorque > torqueLimit) ? torqueLimit : desiredTorque;
411 desiredTorque = (desiredTorque < -torqueLimit) ? -torqueLimit : desiredTorque;
413 debugOutputData.getWriteBuffer().desired_torques[jointNames[i]] =
414 jointDesiredTorques(i);
415 debugOutputData.getWriteBuffer().desired_nullspaceJoint[jointNames[i]] =
416 desiredNullSpaceJointValues(i);
418 targets.at(i)->torque = desiredTorque;
419 if (!targets.at(i)->isValid())
422 <<
"Torque controller target is invalid - setting to zero! set value: "
423 << targets.at(i)->torque;
424 targets.at(i)->torque = 0.0f;
429 debugOutputData.getWriteBuffer().forceDesired_x = jointControlWrench(0);
430 debugOutputData.getWriteBuffer().forceDesired_y = jointControlWrench(1);
431 debugOutputData.getWriteBuffer().forceDesired_z = jointControlWrench(2);
432 debugOutputData.getWriteBuffer().forceDesired_rx = jointControlWrench(3);
433 debugOutputData.getWriteBuffer().forceDesired_ry = jointControlWrench(4);
434 debugOutputData.getWriteBuffer().forceDesired_rz = jointControlWrench(5);
436 debugOutputData.getWriteBuffer().impedanceKp_x = kpos(0);
437 debugOutputData.getWriteBuffer().impedanceKp_y = kpos(1);
438 debugOutputData.getWriteBuffer().impedanceKp_z = kpos(2);
439 debugOutputData.getWriteBuffer().impedanceKp_rx = kori(0);
440 debugOutputData.getWriteBuffer().impedanceKp_ry = kori(1);
441 debugOutputData.getWriteBuffer().impedanceKp_rz = kori(2);
443 debugOutputData.getWriteBuffer().forceInRoot_x = filteredForce(0);
444 debugOutputData.getWriteBuffer().forceInRoot_y = filteredForce(1);
445 debugOutputData.getWriteBuffer().forceInRoot_z = filteredForce(2);
450 debugOutputData.getWriteBuffer().vel_x = currentTwist(0);
451 debugOutputData.getWriteBuffer().vel_y = currentTwist(1);
452 debugOutputData.getWriteBuffer().vel_z = currentTwist(2);
457 debugOutputData.getWriteBuffer().targetPose_x = targetPose(0, 3);
458 debugOutputData.getWriteBuffer().targetPose_y = targetPose(1, 3);
459 debugOutputData.getWriteBuffer().targetPose_z = targetPose(2, 3);
460 VirtualRobot::MathTools::Quaternion targetQuat =
461 VirtualRobot::MathTools::eigen4f2quat(targetPose);
462 debugOutputData.getWriteBuffer().targetPose_qw = targetQuat.w;
463 debugOutputData.getWriteBuffer().targetPose_qx = targetQuat.x;
464 debugOutputData.getWriteBuffer().targetPose_qy = targetQuat.y;
465 debugOutputData.getWriteBuffer().targetPose_qz = targetQuat.z;
467 debugOutputData.getWriteBuffer().currentPose_x = currentPose(0, 3);
468 debugOutputData.getWriteBuffer().currentPose_y = currentPose(1, 3);
469 debugOutputData.getWriteBuffer().currentPose_z = currentPose(2, 3);
470 VirtualRobot::MathTools::Quaternion currentQuat =
471 VirtualRobot::MathTools::eigen4f2quat(currentPose);
472 debugOutputData.getWriteBuffer().currentPose_qw = currentQuat.w;
473 debugOutputData.getWriteBuffer().currentPose_qx = currentQuat.x;
474 debugOutputData.getWriteBuffer().currentPose_qy = currentQuat.y;
475 debugOutputData.getWriteBuffer().currentPose_qz = currentQuat.z;
476 debugOutputData.getWriteBuffer().deltaT = deltaT;
478 debugOutputData.commitWrite();
750 auto values = debugOutputData.getUpToDateReadBuffer().desired_torques;
751 for (
auto& pair : values)
753 datafields[
"torqueDesired_" + pair.first] =
new Variant(pair.second);
756 auto values_null = debugOutputData.getUpToDateReadBuffer().desired_nullspaceJoint;
757 for (
auto& pair : values_null)
759 datafields[
"nullspaceDesired_" + pair.first] =
new Variant(pair.second);
762 datafields[
"canVal"] =
new Variant(debugOutputData.getUpToDateReadBuffer().currentCanVal);
763 datafields[
"mpcfactor"] =
new Variant(debugOutputData.getUpToDateReadBuffer().mpcfactor);
764 datafields[
"targetPose_x"] =
765 new Variant(debugOutputData.getUpToDateReadBuffer().targetPose_x);
766 datafields[
"targetPose_y"] =
767 new Variant(debugOutputData.getUpToDateReadBuffer().targetPose_y);
768 datafields[
"targetPose_z"] =
769 new Variant(debugOutputData.getUpToDateReadBuffer().targetPose_z);
770 datafields[
"targetPose_qw"] =
771 new Variant(debugOutputData.getUpToDateReadBuffer().targetPose_qw);
772 datafields[
"targetPose_qx"] =
773 new Variant(debugOutputData.getUpToDateReadBuffer().targetPose_qx);
774 datafields[
"targetPose_qy"] =
775 new Variant(debugOutputData.getUpToDateReadBuffer().targetPose_qy);
776 datafields[
"targetPose_qz"] =
777 new Variant(debugOutputData.getUpToDateReadBuffer().targetPose_qz);
779 datafields[
"impedanceKp_x"] =
780 new Variant(debugOutputData.getUpToDateReadBuffer().impedanceKp_x);
781 datafields[
"impedanceKp_y"] =
782 new Variant(debugOutputData.getUpToDateReadBuffer().impedanceKp_y);
783 datafields[
"impedanceKp_z"] =
784 new Variant(debugOutputData.getUpToDateReadBuffer().impedanceKp_z);
785 datafields[
"impedanceKp_rx"] =
786 new Variant(debugOutputData.getUpToDateReadBuffer().impedanceKp_rx);
787 datafields[
"impedanceKp_ry"] =
788 new Variant(debugOutputData.getUpToDateReadBuffer().impedanceKp_ry);
789 datafields[
"impedanceKp_rz"] =
790 new Variant(debugOutputData.getUpToDateReadBuffer().impedanceKp_rz);
792 datafields[
"currentPose_x"] =
793 new Variant(debugOutputData.getUpToDateReadBuffer().currentPose_x);
794 datafields[
"currentPose_y"] =
795 new Variant(debugOutputData.getUpToDateReadBuffer().currentPose_y);
796 datafields[
"currentPose_z"] =
797 new Variant(debugOutputData.getUpToDateReadBuffer().currentPose_z);
798 datafields[
"currentPose_qw"] =
799 new Variant(debugOutputData.getUpToDateReadBuffer().currentPose_qw);
800 datafields[
"currentPose_qx"] =
801 new Variant(debugOutputData.getUpToDateReadBuffer().currentPose_qx);
802 datafields[
"currentPose_qy"] =
803 new Variant(debugOutputData.getUpToDateReadBuffer().currentPose_qy);
804 datafields[
"currentPose_qz"] =
805 new Variant(debugOutputData.getUpToDateReadBuffer().currentPose_qz);
807 datafields[
"forceDesired_x"] =
808 new Variant(debugOutputData.getUpToDateReadBuffer().forceDesired_x);
809 datafields[
"forceDesired_y"] =
810 new Variant(debugOutputData.getUpToDateReadBuffer().forceDesired_y);
811 datafields[
"forceDesired_z"] =
812 new Variant(debugOutputData.getUpToDateReadBuffer().forceDesired_z);
813 datafields[
"forceDesired_rx"] =
814 new Variant(debugOutputData.getUpToDateReadBuffer().forceDesired_rx);
815 datafields[
"forceDesired_ry"] =
816 new Variant(debugOutputData.getUpToDateReadBuffer().forceDesired_ry);
817 datafields[
"forceDesired_rz"] =
818 new Variant(debugOutputData.getUpToDateReadBuffer().forceDesired_rz);
820 datafields[
"forceInRoot_x"] =
821 new Variant(debugOutputData.getUpToDateReadBuffer().forceInRoot_x);
822 datafields[
"forceInRoot_y"] =
823 new Variant(debugOutputData.getUpToDateReadBuffer().forceInRoot_y);
824 datafields[
"forceInRoot_z"] =
825 new Variant(debugOutputData.getUpToDateReadBuffer().forceInRoot_z);
827 datafields[
"vel_x"] =
new Variant(debugOutputData.getUpToDateReadBuffer().vel_x);
828 datafields[
"vel_y"] =
new Variant(debugOutputData.getUpToDateReadBuffer().vel_y);
829 datafields[
"vel_z"] =
new Variant(debugOutputData.getUpToDateReadBuffer().vel_z);
831 datafields[
"deltaT"] =
new Variant(debugOutputData.getUpToDateReadBuffer().deltaT);
833 std::string channelName = cfg->nodeSetName +
"_TaskSpaceImpedanceControl";
834 debugObs->setDebugChannel(channelName, datafields);