3 #include <boost/archive/text_iarchive.hpp>
4 #include <boost/archive/text_oarchive.hpp>
10 NJointControllerRegistration<NJointTSDMPController>
14 const armarx::NJointControllerConfigPtr& config,
18 cfg = NJointTaskSpaceDMPControllerConfigPtr::dynamicCast(config);
20 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(cfg->nodeSetName);
21 jointNames = rns->getNodeNames();
23 for (
size_t i = 0; i < rns->getSize(); ++i)
25 std::string jointName = rns->getNode(i)->getName();
28 targets.push_back(ct->
asA<ControlTarget1DoFActuatorVelocity>());
30 const SensorValue1DoFActuatorTorque* torqueSensor =
31 sv->
asA<SensorValue1DoFActuatorTorque>();
32 const SensorValue1DoFActuatorVelocity* velocitySensor =
33 sv->
asA<SensorValue1DoFActuatorVelocity>();
34 const SensorValue1DoFGravityTorque* gravityTorqueSensor =
35 sv->
asA<SensorValue1DoFGravityTorque>();
36 const SensorValue1DoFActuatorPosition* positionSensor =
37 sv->
asA<SensorValue1DoFActuatorPosition>();
42 if (!gravityTorqueSensor)
44 ARMARX_WARNING <<
"No Gravity Torque sensor available for " << jointName;
47 torqueSensors.push_back(torqueSensor);
48 gravityTorqueSensors.push_back(gravityTorqueSensor);
49 velocitySensors.push_back(velocitySensor);
50 positionSensors.push_back(positionSensor);
53 tcp = (cfg->tcpName.empty()) ? rns->getTCP() :
rtGetRobot()->getRobotNode(cfg->tcpName);
54 refFrame = (cfg->frameName.empty()) ? rns->getRobot()->getRootNode()
60 nodeSetName = cfg->nodeSetName;
61 torquePIDs.resize(tcpController->rns->getSize(), pidController());
63 ik.reset(
new VirtualRobot::DifferentialIK(
64 rns, refFrame, VirtualRobot::JacobiProvider::eSVDDamped));
71 taskSpaceDMPConfig.
DMPMode = cfg->dmpMode;
72 taskSpaceDMPConfig.
DMPStyle = cfg->dmpStyle;
89 RTToControllerData initSensorData;
90 initSensorData.deltaT = 0;
91 initSensorData.currentTime = 0;
92 initSensorData.currentPose.setZero();
93 initSensorData.currentTwist.setZero();
96 targetVels.setZero(6);
99 initData.
targetPose = refFrame->toLocalCoordinateSystem(tcp->getGlobalPose());
101 initData.
torqueKp.resize(tcpController->rns->getSize(), 0);
102 initData.
torqueKd.resize(tcpController->rns->getSize(), 0);
106 debugName = cfg->debugName;
108 KpF = cfg->Kp_LinearVel;
109 KoF = cfg->Kp_AngularVel;
110 DpF = cfg->Kd_LinearVel;
111 DoF = cfg->Kd_AngularVel;
113 filtered_qvel.setZero(targets.size());
114 vel_filter_factor = cfg->vel_filter;
116 filtered_position.setZero(3);
117 pos_filter_factor = cfg->pos_filter;
123 jointLowLimits.setZero(targets.size());
124 jointHighLimits.setZero(targets.size());
125 for (
size_t i = 0; i < rns->getSize(); i++)
127 VirtualRobot::RobotNodePtr rn = rns->getAllRobotNodes().at(i);
129 jointLowLimits(i) = rn->getJointLimitLo();
130 jointHighLimits(i) = rn->getJointLimitHi();
135 RTToUserData initInterfaceData;
143 return "NJointTSDMPController";
161 Eigen::VectorXf currentTwist = rt2CtrlData.
getReadBuffer().currentTwist;
164 dmpCtrl->flow(deltaT, currentPose, currentTwist);
166 if (dmpCtrl->canVal < 1e-8)
170 targetVels = dmpCtrl->getTargetVelocity();
171 targetPose = dmpCtrl->getTargetPoseMat();
172 std::vector<double> targetState = dmpCtrl->getTargetPose();
174 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"x_vel"] = targetVels(0);
175 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"y_vel"] = targetVels(1);
176 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"z_vel"] = targetVels(2);
177 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"roll_vel"] = targetVels(3);
178 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"pitch_vel"] = targetVels(4);
179 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"yaw_vel"] = targetVels(5);
180 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_x"] = targetState[0];
181 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_y"] = targetState[1];
182 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_z"] = targetState[2];
183 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_qw"] = targetState[3];
184 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_qx"] = targetState[4];
185 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_qy"] = targetState[5];
186 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_qz"] = targetState[6];
187 debugOutputData.
getWriteBuffer().currentPose[
"currentPose_x"] = currentPose(0, 3);
188 debugOutputData.
getWriteBuffer().currentPose[
"currentPose_y"] = currentPose(1, 3);
189 debugOutputData.
getWriteBuffer().currentPose[
"currentPose_z"] = currentPose(2, 3);
192 VirtualRobot::MathTools::eigen4f2quat(currentPose);
193 debugOutputData.
getWriteBuffer().currentPose[
"currentPose_qw"] = currentQ.w;
194 debugOutputData.
getWriteBuffer().currentPose[
"currentPose_qx"] = currentQ.x;
195 debugOutputData.
getWriteBuffer().currentPose[
"currentPose_qy"] = currentQ.y;
196 debugOutputData.
getWriteBuffer().currentPose[
"currentPose_qz"] = currentQ.z;
197 debugOutputData.
getWriteBuffer().currentCanVal = dmpCtrl->debugData.canVal;
198 debugOutputData.
getWriteBuffer().mpcFactor = dmpCtrl->debugData.mpcFactor;
199 debugOutputData.
getWriteBuffer().error = dmpCtrl->debugData.poseError;
200 debugOutputData.
getWriteBuffer().posError = dmpCtrl->debugData.posiError;
201 debugOutputData.
getWriteBuffer().oriError = dmpCtrl->debugData.oriError;
213 const Eigen::VectorXf& nullspaceVel,
216 Eigen::MatrixXf jacobi = ik->getJacobianMatrix(tcp, mode);
218 Eigen::FullPivLU<Eigen::MatrixXf> lu_decomp(jacobi);
220 Eigen::MatrixXf nullspace = lu_decomp.kernel();
221 Eigen::VectorXf nsv = Eigen::VectorXf::Zero(nullspace.rows());
222 for (
int i = 0; i < nullspace.cols(); i++)
224 float squaredNorm = nullspace.col(i).squaredNorm();
226 if (squaredNorm > 1.0e-32f)
228 nsv += nullspace.col(i) * nullspace.col(i).dot(nullspaceVel) /
229 nullspace.col(i).squaredNorm();
233 Eigen::MatrixXf inv =
234 ik->computePseudoInverseJacobianMatrix(jacobi, ik->getJacobiRegularization(mode));
236 Eigen::VectorXf jointVel = inv * cartesianVel;
245 Eigen::Matrix4f currentPose = refFrame->toLocalCoordinateSystem(tcp->getGlobalPose());
251 filtered_position = currentPose.block<3, 1>(0, 3);
254 for (
size_t i = 0; i < targets.size(); ++i)
256 targets.at(i)->velocity = 0;
262 filtered_position = (1 - pos_filter_factor) * filtered_position +
263 pos_filter_factor * currentPose.block<3, 1>(0, 3);
266 double deltaT = timeSinceLastIteration.toSecondsDouble();
268 Eigen::MatrixXf jacobi =
269 ik->getJacobianMatrix(tcp, VirtualRobot::IKSolver::CartesianSelection::All);
271 Eigen::VectorXf qvel(velocitySensors.size());
272 for (
size_t i = 0; i < velocitySensors.size(); ++i)
274 qvel(i) = velocitySensors[i]->velocity;
277 filtered_qvel = (1 - vel_filter_factor) * filtered_qvel + vel_filter_factor * qvel;
278 Eigen::VectorXf tcptwist = jacobi * filtered_qvel;
292 Eigen::VectorXf jointTargetVelocities = Eigen::VectorXf::Zero(targets.size());
299 targetPose.block<3, 3>(0, 0) * currentPose.block<3, 3>(0, 0).inverse();
300 Eigen::Vector3f errorRPY = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
303 rtTargetVel.block<3, 1>(0, 0) =
304 KpF * (targetPose.block<3, 1>(0, 3) - currentPose.block<3, 1>(0, 3)) +
305 DpF * (-tcptwist.block<3, 1>(0, 0));
307 rtTargetVel.block<3, 1>(3, 0) =
308 KoF * errorRPY + DoF * (targetVel.block<3, 1>(3, 0) - tcptwist.block<3, 1>(3, 0));
312 float normLinearVelocity = rtTargetVel.block<3, 1>(0, 0).
norm();
313 if (normLinearVelocity > cfg->maxLinearVel)
315 rtTargetVel.block<3, 1>(0, 0) =
316 cfg->maxLinearVel * rtTargetVel.block<3, 1>(0, 0) / normLinearVelocity;
319 float normAngularVelocity = rtTargetVel.block<3, 1>(3, 0).
norm();
320 if (normAngularVelocity > cfg->maxAngularVel)
322 rtTargetVel.block<3, 1>(3, 0) =
323 cfg->maxAngularVel * rtTargetVel.block<3, 1>(3, 0) / normAngularVelocity;
334 Eigen::VectorXf jnv = Eigen::VectorXf::Zero(tcpController->rns->getSize());
336 if (jointLimitAvoidanceKp > 0)
338 jnv += jointLimitAvoidanceKp * tcpController->calculateJointLimitAvoidance();
340 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
346 jointTargetVelocities =
347 calcIK(rtTargetVel, jnv, VirtualRobot::IKSolver::CartesianSelection::All);
353 for (
size_t i = 0; i < targets.size(); ++i)
355 targets.at(i)->velocity = jointTargetVelocities(i);
357 if (!targets.at(i)->isValid() || fabs(targets.at(i)->velocity) > cfg->maxJointVelocity)
359 targets.at(i)->velocity = 0.0f;
362 rtDebugData.
getWriteBuffer().targetJointVels = jointTargetVelocities;
373 dmpCtrl->learnDMPFromFiles(fileNames);
380 dmpCtrl->setSpeed(times);
385 const Ice::DoubleSeq& viapoint,
389 dmpCtrl->setViaPose(u, viapoint);
396 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
399 torqueKp.at(tcpController->rns->getNode(i)->getName());
406 const StringFloatDictionary& nullspaceJointVelocities,
410 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
413 nullspaceJointVelocities.at(tcpController->rns->getNode(i)->getName());
436 dmpCtrl->removeAllViaPoints();
444 dmpCtrl->setGoalPoseVec(goals);
450 dmpCtrl->pauseController();
456 dmpCtrl->resumeController();
479 return dmpCtrl->saveDMPToString();
485 dmpCtrl->loadDMPFromString(dmpString);
486 return dmpCtrl->dmpPtr->defaultGoal;
503 return VirtualRobot::IKSolver::CartesianSelection::All;
528 dmpCtrl->prepareExecution(dmpCtrl->eigen4f2vec(pose), goals);
553 dmpCtrl->config.motionTimeDuration = timeDuration;
554 dmpCtrl->prepareExecution(dmpCtrl->eigen4f2vec(pose), goals);
576 std::string datafieldName = debugName;
581 datafieldName = pair.first +
"_" + debugName;
582 datafields[datafieldName] =
new Variant(pair.second);
586 for (
auto& pair : dmpTargets)
588 datafieldName = pair.first +
"_" + debugName;
589 datafields[datafieldName] =
new Variant(pair.second);
593 for (
auto& pair : currentPose)
595 datafieldName = pair.first +
"_" + debugName;
596 datafields[datafieldName] =
new Variant(pair.second);
599 datafieldName =
"canVal_" + debugName;
600 datafields[datafieldName] =
602 datafieldName =
"mpcFactor_" + debugName;
604 datafieldName =
"error_" + debugName;
606 datafieldName =
"posError_" + debugName;
608 datafieldName =
"oriError_" + debugName;
610 datafieldName =
"deltaT_" + debugName;
615 for (
int i = 0; i < targetJoints.size(); ++i)
617 datafieldName = jointNames[i] +
"_velocity";
618 datafields[datafieldName] =
new Variant(targetJoints[i]);
621 datafieldName =
"DMPController_" + debugName;
622 debugObs->setDebugChannel(datafieldName, datafields);
630 runTask(
"NJointTSDMPController",
635 while (
getState() == eManagedIceObjectStarted)
641 c.waitForCycleDuration();
655 dmpCtrl->setWeights(weights);
661 DMP::DVec2d res = dmpCtrl->getWeights();
663 for (
size_t i = 0; i < res.size(); ++i)
665 std::vector<double> cvec;
666 for (
size_t j = 0; j < res[i].size(); ++j)
668 cvec.push_back(res[i][j]);
670 resvec.push_back(cvec);