2 #include <VirtualRobot/MathTools.h>
6 NJointControllerRegistration<NJointCCDMPController>
10 const armarx::NJointControllerConfigPtr& config,
14 cfg = NJointCCDMPControllerConfigPtr::dynamicCast(config);
18 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(cfg->nodeSetName);
21 for (
size_t i = 0; i < rns->getSize(); ++i)
23 std::string jointName = rns->getNode(i)->getName();
26 targets.push_back(ct->
asA<ControlTarget1DoFActuatorVelocity>());
28 const SensorValue1DoFActuatorTorque* torqueSensor =
29 sv->
asA<SensorValue1DoFActuatorTorque>();
30 const SensorValue1DoFGravityTorque* gravityTorqueSensor =
31 sv->
asA<SensorValue1DoFGravityTorque>();
36 if (!gravityTorqueSensor)
38 ARMARX_WARNING <<
"No Gravity Torque sensor available for " << jointName;
41 torqueSensors.push_back(torqueSensor);
42 gravityTorqueSensors.push_back(gravityTorqueSensor);
45 tcp = (cfg->tcpName.empty()) ? rns->getTCP() :
rtGetRobot()->getRobotNode(cfg->tcpName);
50 nodeSetName = cfg->nodeSetName;
51 torquePIDs.resize(tcpController->rns->getSize(), pidController());
54 ik.reset(
new VirtualRobot::DifferentialIK(
55 rns, rns->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
58 isDisturbance =
false;
60 dmpPtrList.resize(cfg->dmpNum);
61 canVals.resize(cfg->dmpNum);
62 timeDurations = cfg->timeDurations;
63 dmpTypes = cfg->dmpTypes;
64 for (
size_t i = 0; i < dmpPtrList.size(); ++i)
66 dmpPtrList[i].reset(
new DMP::UMITSMP(cfg->kernelSize, 2, cfg->tau));
67 canVals[i] = timeDurations[i];
73 phaseDist0 = cfg->phaseDist0;
74 phaseDist1 = cfg->phaseDist1;
75 phaseKpPos = cfg->phaseKpPos;
76 phaseKpOri = cfg->phaseKpOri;
78 posToOriRatio = cfg->posToOriRatio;
83 tcpPosition(0) = pose(0, 3);
84 tcpPosition(1) = pose(1, 3);
85 tcpPosition(2) = pose(2, 3);
87 tcpOrientation.w() = tcpQ.w;
88 tcpOrientation.x() = tcpQ.x;
89 tcpOrientation.y() = tcpQ.y;
90 tcpOrientation.z() = tcpQ.z;
92 NJointCCDMPControllerSensorData initSensorData;
93 initSensorData.deltaT = 0;
94 initSensorData.currentTime = 0;
95 initSensorData.currentPose = pose;
99 currentStates.resize(cfg->dmpNum);
100 targetSubStates.resize(cfg->dmpNum);
101 targetState.resize(7);
103 targetVels.resize(6);
104 targetVels.setZero();
109 initData.
torqueKp.resize(tcpController->rns->getSize(), 0);
110 initData.
torqueKd.resize(tcpController->rns->getSize(), 0);
116 amplitudes = cfg->amplitudes;
122 return "NJointCCDMPController";
136 Eigen::Vector3f currentPosition;
137 currentPosition << currentPose(0, 3), currentPose(1, 3), currentPose(2, 3);
139 for (
size_t i = 0; i < 3; ++i)
141 posError += pow(currentPosition(i) - targetState[i], 2);
143 posError =
sqrt(posError);
147 VirtualRobot::MathTools::eigen4f2quat(currentPose);
150 currentQ.w() = cQuat.w;
151 currentQ.x() = cQuat.x;
152 currentQ.y() = cQuat.y;
153 currentQ.z() = cQuat.z;
154 targetQ.w() = targetState[3];
155 targetQ.x() = targetState[4];
156 targetQ.y() = targetState[5];
157 targetQ.z() = targetState[6];
159 double oriError = targetQ.angularDistance(currentQ);
162 oriError = 2 *
M_PI - oriError;
165 double error = posError + posToOriRatio * oriError;
170 phaseDist = phaseDist1;
174 phaseDist = phaseDist0;
177 double phaseStop = phaseL / (1 + exp(-phaseK * (error - phaseDist)));
178 double mpcFactor = 1 - (phaseStop / phaseL);
183 isDisturbance =
true;
188 isDisturbance =
false;
194 Eigen::VectorXf dmpVels;
197 for (
size_t i = 0; i < static_cast<size_t>(cfg->dmpNum); ++i)
199 double timeDuration = timeDurations[i];
200 std::string dmpType = dmpTypes[i];
203 if (dmpType ==
"Periodic")
205 if (canVals[i] <= 1e-8)
207 canVals[i] = timeDuration;
212 if (canVals[i] > 1e-8)
214 DMP::UMITSMPPtr dmpPtr = dmpPtrList[i];
215 double dmpDeltaT = deltaT / timeDuration;
216 double tau = dmpPtr->getTemporalFactor();
217 canVals[i] -= 1 / tau * deltaT * 1 / (1 + phaseStop);
220 currentStates[i] = dmpPtr->calculateDirectlyVelocity(
221 currentStates[i], canVals[i] / timeDurations[i], dmpDeltaT, targetSubStates[i]);
224 for (
size_t j = 0; j < 3; ++j)
226 dmpVels(j) += currentStates[i][j].vel / timeDurations[i];
230 quatVel0.w() = currentStates[i][3].vel;
231 quatVel0.x() = currentStates[i][4].vel;
232 quatVel0.y() = currentStates[i][5].vel;
233 quatVel0.z() = currentStates[i][6].vel;
235 dmpQ.w() = currentStates[i][3].pos;
236 dmpQ.x() = currentStates[i][4].pos;
237 dmpQ.y() = currentStates[i][5].pos;
238 dmpQ.z() = currentStates[i][6].pos;
242 2 * aVtmp0.w(), 2 * aVtmp0.x(), 2 * aVtmp0.y(), 2 * aVtmp0.z()};
245 Eigen::Vector3f angularVelVec;
246 angularVelVec << angularVel0.x() / timeDurations[i],
247 angularVel0.y() / timeDurations[i], angularVel0.z() / timeDurations[i];
249 angularVelVec = targetPose.block<3, 3>(0, 0) * angularVelVec;
251 ARMARX_INFO <<
"i: " << i <<
" angularVelVec: " << angularVelVec;
252 dmpVels(3) += angularVelVec(0);
253 dmpVels(4) += angularVelVec(1);
254 dmpVels(5) += angularVelVec(2);
261 VirtualRobot::MathTools::quat2eigen4f(targetSubStates[i][4],
262 targetSubStates[i][5],
263 targetSubStates[i][6],
264 targetSubStates[i][3]);
265 targetSubMat(0, 3) = targetSubStates[i][0];
266 targetSubMat(1, 3) = targetSubStates[i][1];
267 targetSubMat(2, 3) = targetSubStates[i][2];
269 targetPose = targetPose * targetSubMat;
273 for (
size_t i = 0; i < 3; i++)
275 double vel0 = dmpVels(i);
276 double vel1 = phaseKpPos * (targetState[i] - currentPose(i, 3));
277 targetVels(i) = mpcFactor * vel0 + (1 - mpcFactor) * vel1;
283 phaseKpOri * diffQ.x(),
284 phaseKpOri * diffQ.y(),
285 phaseKpOri * diffQ.z()};
289 2 * aVtmp1.w(), 2 * aVtmp1.x(), 2 * aVtmp1.y(), 2 * aVtmp1.z()};
290 targetVels(3) = mpcFactor * dmpVels(3) + (1 - mpcFactor) * angularVel1.x();
291 targetVels(4) = mpcFactor * dmpVels(4) + (1 - mpcFactor) * angularVel1.y();
292 targetVels(5) = mpcFactor * dmpVels(5) + (1 - mpcFactor) * angularVel1.z();
296 VirtualRobot::MathTools::eigen4f2quat(targetPose);
297 targetState[0] = targetPose(0, 3);
298 targetState[1] = targetPose(1, 3);
299 targetState[2] = targetPose(2, 3);
300 targetState[3] = tQuat.w;
301 targetState[4] = tQuat.x;
302 targetState[5] = tQuat.y;
303 targetState[6] = tQuat.z;
306 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"x_vel"] = targetVels(0);
307 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"y_vel"] = targetVels(1);
308 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"z_vel"] = targetVels(2);
309 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"roll_vel"] = targetVels(3);
310 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"pitch_vel"] = targetVels(4);
311 debugOutputData.
getWriteBuffer().latestTargetVelocities[
"yaw_vel"] = targetVels(5);
312 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_x"] = targetState[0];
313 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_y"] = targetState[1];
314 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_z"] = targetState[2];
315 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_qw"] = targetState[3];
316 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_qx"] = targetState[4];
317 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_qy"] = targetState[5];
318 debugOutputData.
getWriteBuffer().dmpTargets[
"dmp_qz"] = targetState[6];
320 debugOutputData.
getWriteBuffer().realTCP[
"real_x"] = currentPosition[0];
321 debugOutputData.
getWriteBuffer().realTCP[
"real_y"] = currentPosition[1];
322 debugOutputData.
getWriteBuffer().realTCP[
"real_z"] = currentPosition[2];
350 double deltaT = timeSinceLastIteration.toSecondsDouble();
351 controllerSensorData.
getWriteBuffer().currentPose = tcp->getPoseInRootFrame();
357 Eigen::MatrixXf jacobi =
358 ik->getJacobianMatrix(tcp, VirtualRobot::IKSolver::CartesianSelection::All);
361 Eigen::MatrixXf jtpinv = ik->computePseudoInverseJacobianMatrix(
362 jacobi, ik->getJacobiRegularization(VirtualRobot::IKSolver::CartesianSelection::All));
366 for (
size_t i = 0; i < targets.size(); ++i)
368 targets.at(i)->velocity = jnv(i);
375 const Ice::StringSeq& fileNames,
378 DMP::Vec<DMP::SampledTrajectoryV2> trajs;
382 DMP::Vec<DMP::DMPState> starts;
384 for (
size_t i = 0; i < fileNames.size(); ++i)
386 DMP::SampledTrajectoryV2 traj;
387 traj.readFromCSVFile(fileNames.at(i));
389 trajs.push_back(traj);
393 goals.resize(traj.dim());
394 starts.resize(traj.dim());
395 for (
size_t j = 0; j < goals.size(); ++j)
397 goals[j] = traj.rbegin()->getPosition(j);
398 starts[j].pos = traj.begin()->getPosition(j);
399 starts[j].vel = traj.begin()->getDeriv(j, 1) * timeDurations[dmpId];
405 ratios.push_back(1.0);
409 ratios.push_back(0.0);
413 dmpPtrList[dmpId]->learnFromTrajectories(trajs);
414 dmpPtrList[dmpId]->styleParas = dmpPtrList[dmpId]->getStyleParasWithRatio(ratios);
417 DMP::Vec<DMP::DMPState> currentState;
420 for (
size_t i = 0; i < 3; i++)
422 DMP::DMPState currentPos;
423 currentPos.pos = tcpPosition(i);
425 currentState.push_back(currentPos);
428 DMP::DMPState currentPos;
429 currentPos.pos = tcpOrientation.w();
431 currentState.push_back(currentPos);
433 currentPos.pos = tcpOrientation.x();
435 currentState.push_back(currentPos);
437 currentPos.pos = tcpOrientation.y();
439 currentState.push_back(currentPos);
441 currentPos.pos = tcpOrientation.z();
443 currentState.push_back(currentPos);
447 currentState = starts;
449 for (
size_t i = 0; i < 3; i++)
451 targetState[i] = tcpPosition(i);
454 targetState[3] = tcpOrientation.w();
455 targetState[4] = tcpOrientation.x();
456 targetState[5] = tcpOrientation.y();
457 targetState[6] = tcpOrientation.z();
459 currentStates[dmpId] = currentState;
461 dmpPtrList[dmpId]->prepareExecution(goals, currentState, 1, tau);
462 dmpPtrList[dmpId]->setTemporalFactor(tau);
464 learnedDMP.push_back(dmpId);
471 const Ice::DoubleSeq& viapoint,
476 dmpPtrList[dmpId]->setViaPoint(u, viapoint);
482 setViaPoints(dmpId, dmpPtrList[dmpId]->getUMin(), goals, ice);
511 return VirtualRobot::IKSolver::CartesianSelection::All;
522 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
525 torqueKp.at(tcpController->rns->getNode(i)->getName());
532 const StringFloatDictionary& nullspaceJointVelocities,
536 for (
size_t i = 0; i < tcpController->rns->getSize(); i++)
539 nullspaceJointVelocities.at(tcpController->rns->getNode(i)->getName());
548 const auto dmpNum =
static_cast<std::size_t
>(cfg->dmpNum);
550 if (dmpNum != dmpTypes.size() || dmpNum != dmpPtrList.size() ||
551 dmpNum != learnedDMP.size() || dmpNum != canVals.size() ||
552 dmpNum != currentStates.size() || dmpNum != targetSubStates.size())
554 ARMARX_ERROR <<
"Error: cannot run CCDMP controller. The reason is that some "
555 "parameters have different sizes";
559 controllerTask->start();
566 dmpPtrList[dmpId]->setTemporalFactor(tau);
588 datafields[pair.first] =
new Variant(pair.second);
592 for (
auto& pair : dmpTargets)
594 datafields[pair.first] =
new Variant(pair.second);
598 for (
auto& pair : realTCP)
600 datafields[pair.first] =
new Variant(pair.second);
612 debugObs->setDebugChannel(
"DMPController", datafields);
626 controllerTask->stop();