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>
18 NJointControllerRegistration<NJointCCDMPController>
22 const armarx::NJointControllerConfigPtr& config,
26 cfg = NJointCCDMPControllerConfigPtr::dynamicCast(config);
30 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(cfg->nodeSetName);
33 for (
size_t i = 0; i < rns->getSize(); ++i)
35 std::string jointName = rns->getNode(i)->getName();
38 targets.push_back(ct->
asA<ControlTarget1DoFActuatorVelocity>());
40 const SensorValue1DoFActuatorTorque* torqueSensor =
41 sv->
asA<SensorValue1DoFActuatorTorque>();
42 const SensorValue1DoFGravityTorque* gravityTorqueSensor =
43 sv->
asA<SensorValue1DoFGravityTorque>();
48 if (!gravityTorqueSensor)
50 ARMARX_WARNING <<
"No Gravity Torque sensor available for " << jointName;
53 torqueSensors.push_back(torqueSensor);
54 gravityTorqueSensors.push_back(gravityTorqueSensor);
57 tcp = (cfg->tcpName.empty()) ? rns->getTCP() :
rtGetRobot()->getRobotNode(cfg->tcpName);
62 nodeSetName = cfg->nodeSetName;
63 torquePIDs.resize(tcpController->rns->getSize(), pidController());
66 ik.reset(
new VirtualRobot::DifferentialIK(
67 rns, rns->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
70 isDisturbance =
false;
72 dmpPtrList.resize(cfg->dmpNum);
73 canVals.resize(cfg->dmpNum);
74 timeDurations = cfg->timeDurations;
75 dmpTypes = cfg->dmpTypes;
76 for (
size_t i = 0; i < dmpPtrList.size(); ++i)
78 dmpPtrList[i].reset(
new DMP::UMITSMP(cfg->kernelSize, 2, cfg->tau));
79 canVals[i] = timeDurations[i];
85 phaseDist0 = cfg->phaseDist0;
86 phaseDist1 = cfg->phaseDist1;
87 phaseKpPos = cfg->phaseKpPos;
88 phaseKpOri = cfg->phaseKpOri;
90 posToOriRatio = cfg->posToOriRatio;
95 tcpPosition(0) = pose(0, 3);
96 tcpPosition(1) = pose(1, 3);
97 tcpPosition(2) = pose(2, 3);
99 tcpOrientation.w() = tcpQ.w;
100 tcpOrientation.x() = tcpQ.x;
101 tcpOrientation.y() = tcpQ.y;
102 tcpOrientation.z() = tcpQ.z;
104 NJointCCDMPControllerSensorData initSensorData;
105 initSensorData.deltaT = 0;
106 initSensorData.currentTime = 0;
107 initSensorData.currentPose = pose;
111 currentStates.resize(cfg->dmpNum);
112 targetSubStates.resize(cfg->dmpNum);
113 targetState.resize(7);
115 targetVels.resize(6);
116 targetVels.setZero();
121 initData.
torqueKp.resize(tcpController->rns->getSize(), 0);
122 initData.
torqueKd.resize(tcpController->rns->getSize(), 0);
128 amplitudes = cfg->amplitudes;
134 return "NJointCCDMPController";
148 Eigen::Vector3f currentPosition;
149 currentPosition << currentPose(0, 3), currentPose(1, 3), currentPose(2, 3);
151 for (
size_t i = 0; i < 3; ++i)
153 posError += pow(currentPosition(i) - targetState[i], 2);
155 posError =
sqrt(posError);
159 VirtualRobot::MathTools::eigen4f2quat(currentPose);
162 currentQ.w() = cQuat.w;
163 currentQ.x() = cQuat.x;
164 currentQ.y() = cQuat.y;
165 currentQ.z() = cQuat.z;
166 targetQ.w() = targetState[3];
167 targetQ.x() = targetState[4];
168 targetQ.y() = targetState[5];
169 targetQ.z() = targetState[6];
171 double oriError = targetQ.angularDistance(currentQ);
174 oriError = 2 *
M_PI - oriError;
177 double error = posError + posToOriRatio * oriError;
182 phaseDist = phaseDist1;
186 phaseDist = phaseDist0;
189 double phaseStop = phaseL / (1 + exp(-phaseK * (error - phaseDist)));
190 double mpcFactor = 1 - (phaseStop / phaseL);
195 isDisturbance =
true;
200 isDisturbance =
false;
206 Eigen::VectorXf dmpVels;
209 for (
size_t i = 0; i < static_cast<size_t>(cfg->dmpNum); ++i)
211 double timeDuration = timeDurations[i];
212 std::string dmpType = dmpTypes[i];
215 if (dmpType ==
"Periodic")
217 if (canVals[i] <= 1e-8)
219 canVals[i] = timeDuration;
224 if (canVals[i] > 1e-8)
227 double dmpDeltaT = deltaT / timeDuration;
228 double tau = dmpPtr->getTemporalFactor();
229 canVals[i] -= 1 / tau * deltaT * 1 / (1 + phaseStop);
232 currentStates[i] = dmpPtr->calculateDirectlyVelocity(
233 currentStates[i], canVals[i] / timeDurations[i], dmpDeltaT, targetSubStates[i]);
236 for (
size_t j = 0; j < 3; ++j)
238 dmpVels(j) += currentStates[i][j].vel / timeDurations[i];
242 quatVel0.w() = currentStates[i][3].vel;
243 quatVel0.x() = currentStates[i][4].vel;
244 quatVel0.y() = currentStates[i][5].vel;
245 quatVel0.z() = currentStates[i][6].vel;
247 dmpQ.w() = currentStates[i][3].pos;
248 dmpQ.x() = currentStates[i][4].pos;
249 dmpQ.y() = currentStates[i][5].pos;
250 dmpQ.z() = currentStates[i][6].pos;
254 2 * aVtmp0.w(), 2 * aVtmp0.x(), 2 * aVtmp0.y(), 2 * aVtmp0.z()};
257 Eigen::Vector3f angularVelVec;
258 angularVelVec << angularVel0.x() / timeDurations[i],
259 angularVel0.y() / timeDurations[i], angularVel0.z() / timeDurations[i];
261 angularVelVec = targetPose.block<3, 3>(0, 0) * angularVelVec;
263 ARMARX_INFO <<
"i: " << i <<
" angularVelVec: " << angularVelVec;
264 dmpVels(3) += angularVelVec(0);
265 dmpVels(4) += angularVelVec(1);
266 dmpVels(5) += angularVelVec(2);
273 VirtualRobot::MathTools::quat2eigen4f(targetSubStates[i][4],
274 targetSubStates[i][5],
275 targetSubStates[i][6],
276 targetSubStates[i][3]);
277 targetSubMat(0, 3) = targetSubStates[i][0];
278 targetSubMat(1, 3) = targetSubStates[i][1];
279 targetSubMat(2, 3) = targetSubStates[i][2];
281 targetPose = targetPose * targetSubMat;
285 for (
size_t i = 0; i < 3; i++)
287 double vel0 = dmpVels(i);
288 double vel1 = phaseKpPos * (targetState[i] - currentPose(i, 3));
289 targetVels(i) = mpcFactor * vel0 + (1 - mpcFactor) * vel1;
295 phaseKpOri * diffQ.x(),
296 phaseKpOri * diffQ.y(),
297 phaseKpOri * diffQ.z()};
301 2 * aVtmp1.w(), 2 * aVtmp1.x(), 2 * aVtmp1.y(), 2 * aVtmp1.z()};
302 targetVels(3) = mpcFactor * dmpVels(3) + (1 - mpcFactor) * angularVel1.x();
303 targetVels(4) = mpcFactor * dmpVels(4) + (1 - mpcFactor) * angularVel1.y();
304 targetVels(5) = mpcFactor * dmpVels(5) + (1 - mpcFactor) * angularVel1.z();
308 VirtualRobot::MathTools::eigen4f2quat(targetPose);
309 targetState[0] = targetPose(0, 3);
310 targetState[1] = targetPose(1, 3);
311 targetState[2] = targetPose(2, 3);
312 targetState[3] = tQuat.w;
313 targetState[4] = tQuat.x;
314 targetState[5] = tQuat.y;
315 targetState[6] = tQuat.z;
318 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"x_vel"] = targetVels(0);
319 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"y_vel"] = targetVels(1);
320 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"z_vel"] = targetVels(2);
321 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"roll_vel"] = targetVels(3);
322 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"pitch_vel"] = targetVels(4);
323 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"yaw_vel"] = targetVels(5);
324 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_x"] = targetState[0];
325 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_y"] = targetState[1];
326 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_z"] = targetState[2];
327 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_qw"] = targetState[3];
328 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_qx"] = targetState[4];
329 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_qy"] = targetState[5];
330 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_qz"] = targetState[6];
332 debugOutputData.
getWriteBuffer().realTCP[
"real_x"] = currentPosition[0];
333 debugOutputData.
getWriteBuffer().realTCP[
"real_y"] = currentPosition[1];
334 debugOutputData.
getWriteBuffer().realTCP[
"real_z"] = currentPosition[2];
361 double deltaT = timeSinceLastIteration.toSecondsDouble();
362 controllerSensorData.
getWriteBuffer().currentPose = tcp->getPoseInRootFrame();
368 Eigen::MatrixXf jacobi =
369 ik->getJacobianMatrix(tcp, VirtualRobot::IKSolver::CartesianSelection::All);
372 Eigen::MatrixXf jtpinv = ik->computePseudoInverseJacobianMatrix(
373 jacobi, ik->getJacobiRegularization(VirtualRobot::IKSolver::CartesianSelection::All));
377 for (
size_t i = 0; i < targets.size(); ++i)
379 targets.at(i)->velocity = jnv(i);
385 const Ice::StringSeq& fileNames,
388 DMP::Vec<DMP::SampledTrajectoryV2> trajs;
392 DMP::Vec<DMP::DMPState> starts;
394 for (
size_t i = 0; i < fileNames.size(); ++i)
396 DMP::SampledTrajectoryV2 traj;
397 traj.readFromCSVFile(fileNames.at(i));
399 trajs.push_back(traj);
403 goals.resize(traj.dim());
404 starts.resize(traj.dim());
405 for (
size_t j = 0; j < goals.size(); ++j)
407 goals[j] = traj.rbegin()->getPosition(j);
408 starts[j].pos = traj.begin()->getPosition(j);
409 starts[j].vel = traj.begin()->getDeriv(j, 1) * timeDurations[dmpId];
415 ratios.push_back(1.0);
419 ratios.push_back(0.0);
423 dmpPtrList[dmpId]->learnFromTrajectories(trajs);
424 dmpPtrList[dmpId]->styleParas = dmpPtrList[dmpId]->getStyleParasWithRatio(ratios);
427 DMP::Vec<DMP::DMPState> currentState;
430 for (
size_t i = 0; i < 3; i++)
432 DMP::DMPState currentPos;
433 currentPos.pos = tcpPosition(i);
435 currentState.push_back(currentPos);
438 DMP::DMPState currentPos;
439 currentPos.pos = tcpOrientation.w();
441 currentState.push_back(currentPos);
443 currentPos.pos = tcpOrientation.x();
445 currentState.push_back(currentPos);
447 currentPos.pos = tcpOrientation.y();
449 currentState.push_back(currentPos);
451 currentPos.pos = tcpOrientation.z();
453 currentState.push_back(currentPos);
457 currentState = starts;
459 for (
size_t i = 0; i < 3; i++)
461 targetState[i] = tcpPosition(i);
464 targetState[3] = tcpOrientation.w();
465 targetState[4] = tcpOrientation.x();
466 targetState[5] = tcpOrientation.y();
467 targetState[6] = tcpOrientation.z();
469 currentStates[dmpId] = currentState;
471 dmpPtrList[dmpId]->prepareExecution(goals, currentState, 1, tau);
472 dmpPtrList[dmpId]->setTemporalFactor(tau);
474 learnedDMP.push_back(dmpId);
481 const Ice::DoubleSeq& viapoint,
486 dmpPtrList[dmpId]->setViaPoint(u, viapoint);
492 setViaPoints(dmpId, dmpPtrList[dmpId]->getUMin(), goals, ice);
521 return VirtualRobot::IKSolver::CartesianSelection::All;
531 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
534 torqueKp.at(tcpController->rns->getNode(i)->getName());
541 const StringFloatDictionary& nullspaceJointVelocities,
545 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
548 nullspaceJointVelocities.at(tcpController->rns->getNode(i)->getName());
557 const auto dmpNum =
static_cast<std::size_t
>(cfg->dmpNum);
559 if (dmpNum != dmpTypes.size() || dmpNum != dmpPtrList.size() ||
560 dmpNum != learnedDMP.size() || dmpNum != canVals.size() ||
561 dmpNum != currentStates.size() || dmpNum != targetSubStates.size())
563 ARMARX_ERROR <<
"Error: cannot run CCDMP controller. The reason is that some "
564 "parameters have different sizes";
568 controllerTask->start();
575 dmpPtrList[dmpId]->setTemporalFactor(tau);
597 datafields[pair.first] =
new Variant(pair.second);
601 for (
auto& pair : dmpTargets)
603 datafields[pair.first] =
new Variant(pair.second);
607 for (
auto& pair : realTCP)
609 datafields[pair.first] =
new Variant(pair.second);
621 debugObs->setDebugChannel(
"DMPController", datafields);
635 controllerTask->stop();