NJointTSDMPController.cpp
Go to the documentation of this file.
2
3#include <boost/archive/text_iarchive.hpp>
4#include <boost/archive/text_oarchive.hpp>
5
6#include <VirtualRobot/MathTools.h>
7#include <VirtualRobot/Nodes/RobotNode.h>
8#include <VirtualRobot/RobotNodeSet.h>
9#include <VirtualRobot/IK/DifferentialIK.h>
10
12
14{
15 NJointControllerRegistration<NJointTSDMPController>
17
19 const armarx::NJointControllerConfigPtr& config,
21 {
23 cfg = NJointTaskSpaceDMPControllerConfigPtr::dynamicCast(config);
24 ARMARX_CHECK_EXPRESSION(!cfg->nodeSetName.empty());
25 VirtualRobot::RobotNodeSetPtr rns = rtGetRobot()->getRobotNodeSet(cfg->nodeSetName);
26 jointNames = rns->getNodeNames();
27 ARMARX_CHECK_EXPRESSION(rns) << cfg->nodeSetName;
28 for (size_t i = 0; i < rns->getSize(); ++i)
29 {
30 std::string jointName = rns->getNode(i)->getName();
31 ControlTargetBase* ct = useControlTarget(jointName, ControlModes::Velocity1DoF);
32 const SensorValueBase* sv = useSensorValue(jointName);
33 targets.push_back(ct->asA<ControlTarget1DoFActuatorVelocity>());
34
35 const SensorValue1DoFActuatorTorque* torqueSensor =
36 sv->asA<SensorValue1DoFActuatorTorque>();
37 const SensorValue1DoFActuatorVelocity* velocitySensor =
38 sv->asA<SensorValue1DoFActuatorVelocity>();
39 const SensorValue1DoFGravityTorque* gravityTorqueSensor =
40 sv->asA<SensorValue1DoFGravityTorque>();
41 const SensorValue1DoFActuatorPosition* positionSensor =
42 sv->asA<SensorValue1DoFActuatorPosition>();
43 if (!torqueSensor)
44 {
45 ARMARX_WARNING << "No Torque sensor available for " << jointName;
46 }
47 if (!gravityTorqueSensor)
48 {
49 ARMARX_WARNING << "No Gravity Torque sensor available for " << jointName;
50 }
51
52 torqueSensors.push_back(torqueSensor);
53 gravityTorqueSensors.push_back(gravityTorqueSensor);
54 velocitySensors.push_back(velocitySensor);
55 positionSensors.push_back(positionSensor);
56 };
57
58 tcp = (cfg->tcpName.empty()) ? rns->getTCP() : rtGetRobot()->getRobotNode(cfg->tcpName);
59 refFrame = (cfg->frameName.empty()) ? rns->getRobot()->getRootNode()
60 : rtGetRobot()->getRobotNode(cfg->frameName);
61 ARMARX_CHECK_EXPRESSION(tcp) << cfg->tcpName;
62
63 // set tcp controller
64 tcpController.reset(new CartesianVelocityController(rns, tcp));
65 nodeSetName = cfg->nodeSetName;
66 torquePIDs.resize(tcpController->rns->getSize(), pidController());
67
68 ik.reset(new VirtualRobot::DifferentialIK(
69 rns, refFrame, VirtualRobot::JacobiProvider::eSVDDamped));
70
71
72 finished = false;
73 tsvmp::TaskSpaceDMPControllerConfig taskSpaceDMPConfig;
74 taskSpaceDMPConfig.motionTimeDuration = cfg->timeDuration;
75 taskSpaceDMPConfig.DMPKernelSize = cfg->kernelSize;
76 taskSpaceDMPConfig.DMPMode = cfg->dmpMode;
77 taskSpaceDMPConfig.DMPStyle = cfg->dmpStyle;
78 taskSpaceDMPConfig.DMPAmplitude = cfg->dmpAmplitude;
79 taskSpaceDMPConfig.phaseStopParas.goDist = cfg->phaseDist0;
80 taskSpaceDMPConfig.phaseStopParas.backDist = cfg->phaseDist1;
81 taskSpaceDMPConfig.phaseStopParas.Kpos = cfg->phaseKpPos;
82 taskSpaceDMPConfig.phaseStopParas.Dpos = 0;
83 taskSpaceDMPConfig.phaseStopParas.Kori = cfg->phaseKpOri;
84 taskSpaceDMPConfig.phaseStopParas.Dori = 0;
85 taskSpaceDMPConfig.phaseStopParas.mm2radi = cfg->posToOriRatio;
86 taskSpaceDMPConfig.phaseStopParas.maxValue = cfg->phaseL;
87 taskSpaceDMPConfig.phaseStopParas.slop = cfg->phaseK;
88
89 dmpCtrl.reset(new tsvmp::TaskSpaceDMPController("default", taskSpaceDMPConfig, false));
90
91 // initialize tcp position and orientation
92
93
94 RTToControllerData initSensorData;
95 initSensorData.deltaT = 0;
96 initSensorData.currentTime = 0;
97 initSensorData.currentPose.setZero();
98 initSensorData.currentTwist.setZero();
99 rt2CtrlData.reinitAllBuffers(initSensorData);
100
101 targetVels.setZero(6);
103 initData.targetTSVel.setZero(6);
104 initData.targetPose = refFrame->toLocalCoordinateSystem(tcp->getGlobalPose());
105 initData.nullspaceJointVelocities.resize(tcpController->rns->getSize(), 0);
106 initData.torqueKp.resize(tcpController->rns->getSize(), 0);
107 initData.torqueKd.resize(tcpController->rns->getSize(), 0);
108 initData.mode = ModeFromIce(cfg->mode);
109 reinitTripleBuffer(initData);
110
111 debugName = cfg->debugName;
112
113 KpF = cfg->Kp_LinearVel;
114 KoF = cfg->Kp_AngularVel;
115 DpF = cfg->Kd_LinearVel;
116 DoF = cfg->Kd_AngularVel;
117
118 filtered_qvel.setZero(targets.size());
119 vel_filter_factor = cfg->vel_filter;
120
121 filtered_position.setZero(3);
122 pos_filter_factor = cfg->pos_filter;
123
124 // jlhigh = rns->getNode("..")->getJointLimitHi();
125 // jllow = rns->getNode("")->getJointLimitLo();
126 firstRun = true;
127
128 jointLowLimits.setZero(targets.size());
129 jointHighLimits.setZero(targets.size());
130 for (size_t i = 0; i < rns->getSize(); i++)
131 {
132 VirtualRobot::RobotNodePtr rn = rns->getAllRobotNodes().at(i);
133
134 jointLowLimits(i) = rn->getJointLimitLo();
135 jointHighLimits(i) = rn->getJointLimitHi();
136 }
137
138 started = false;
139
140 RTToUserData initInterfaceData;
141 initInterfaceData.currentTcpPose = Eigen::Matrix4f::Identity();
142 rt2UserData.reinitAllBuffers(initInterfaceData);
143 }
144
145 std::string
146 NJointTSDMPController::getClassName(const Ice::Current&) const
147 {
148 return "NJointTSDMPController";
149 }
150
151 void
153 {
154 if (!started)
155 {
156 return;
157 }
158
159 if (!rt2CtrlData.updateReadBuffer() || !dmpCtrl)
160 {
161 return;
162 }
163
164 double deltaT = rt2CtrlData.getReadBuffer().deltaT;
165 Eigen::Matrix4f currentPose = rt2CtrlData.getReadBuffer().currentPose;
166 Eigen::VectorXf currentTwist = rt2CtrlData.getReadBuffer().currentTwist;
167
168 LockGuardType guard{controllerMutex};
169 dmpCtrl->flow(deltaT, currentPose, currentTwist);
170
171 if (dmpCtrl->canVal < 1e-8)
172 {
173 finished = true;
174 }
175 targetVels = dmpCtrl->getTargetVelocity();
176 targetPose = dmpCtrl->getTargetPoseMat();
177 std::vector<double> targetState = dmpCtrl->getTargetPose();
178
179 debugOutputData.getWriteBuffer().latestTargetVelocities["x_vel"] = targetVels(0);
180 debugOutputData.getWriteBuffer().latestTargetVelocities["y_vel"] = targetVels(1);
181 debugOutputData.getWriteBuffer().latestTargetVelocities["z_vel"] = targetVels(2);
182 debugOutputData.getWriteBuffer().latestTargetVelocities["roll_vel"] = targetVels(3);
183 debugOutputData.getWriteBuffer().latestTargetVelocities["pitch_vel"] = targetVels(4);
184 debugOutputData.getWriteBuffer().latestTargetVelocities["yaw_vel"] = targetVels(5);
185 debugOutputData.getWriteBuffer().dmpTargets["dmp_x"] = targetState[0];
186 debugOutputData.getWriteBuffer().dmpTargets["dmp_y"] = targetState[1];
187 debugOutputData.getWriteBuffer().dmpTargets["dmp_z"] = targetState[2];
188 debugOutputData.getWriteBuffer().dmpTargets["dmp_qw"] = targetState[3];
189 debugOutputData.getWriteBuffer().dmpTargets["dmp_qx"] = targetState[4];
190 debugOutputData.getWriteBuffer().dmpTargets["dmp_qy"] = targetState[5];
191 debugOutputData.getWriteBuffer().dmpTargets["dmp_qz"] = targetState[6];
192 debugOutputData.getWriteBuffer().currentPose["currentPose_x"] = currentPose(0, 3);
193 debugOutputData.getWriteBuffer().currentPose["currentPose_y"] = currentPose(1, 3);
194 debugOutputData.getWriteBuffer().currentPose["currentPose_z"] = currentPose(2, 3);
195
196 VirtualRobot::MathTools::Quaternion currentQ =
197 VirtualRobot::MathTools::eigen4f2quat(currentPose);
198 debugOutputData.getWriteBuffer().currentPose["currentPose_qw"] = currentQ.w;
199 debugOutputData.getWriteBuffer().currentPose["currentPose_qx"] = currentQ.x;
200 debugOutputData.getWriteBuffer().currentPose["currentPose_qy"] = currentQ.y;
201 debugOutputData.getWriteBuffer().currentPose["currentPose_qz"] = currentQ.z;
202 debugOutputData.getWriteBuffer().currentCanVal = dmpCtrl->debugData.canVal;
203 debugOutputData.getWriteBuffer().mpcFactor = dmpCtrl->debugData.mpcFactor;
204 debugOutputData.getWriteBuffer().error = dmpCtrl->debugData.poseError;
205 debugOutputData.getWriteBuffer().posError = dmpCtrl->debugData.posiError;
206 debugOutputData.getWriteBuffer().oriError = dmpCtrl->debugData.oriError;
207 debugOutputData.getWriteBuffer().deltaT = deltaT;
208
209 debugOutputData.commitWrite();
210
211 getWriterControlStruct().targetTSVel = targetVels;
212 getWriterControlStruct().targetPose = targetPose;
214 }
215
216 Eigen::VectorXf
217 NJointTSDMPController::calcIK(const Eigen::VectorXf& cartesianVel,
218 const Eigen::VectorXf& nullspaceVel,
219 VirtualRobot::IKSolver::CartesianSelection mode)
220 {
221 Eigen::MatrixXf jacobi = ik->getJacobianMatrix(tcp, mode);
222
223 Eigen::FullPivLU<Eigen::MatrixXf> lu_decomp(jacobi);
224
225 Eigen::MatrixXf nullspace = lu_decomp.kernel();
226 Eigen::VectorXf nsv = Eigen::VectorXf::Zero(nullspace.rows());
227 for (int i = 0; i < nullspace.cols(); i++)
228 {
229 float squaredNorm = nullspace.col(i).squaredNorm();
230 // Prevent division by zero
231 if (squaredNorm > 1.0e-32f)
232 {
233 nsv += nullspace.col(i) * nullspace.col(i).dot(nullspaceVel) /
234 nullspace.col(i).squaredNorm();
235 }
236 }
237
238 Eigen::MatrixXf inv =
239 ik->computePseudoInverseJacobianMatrix(jacobi, ik->getJacobiRegularization(mode));
240 // ARMARX_INFO << "inv: " << inv;
241 Eigen::VectorXf jointVel = inv * cartesianVel;
242 // jointVel += nsv;
243 return jointVel;
244 }
245
246 void
247 NJointTSDMPController::rtRun(const IceUtil::Time& sensorValuesTimestamp,
248 const IceUtil::Time& timeSinceLastIteration)
249 {
250 Eigen::Matrix4f currentPose = refFrame->toLocalCoordinateSystem(tcp->getGlobalPose());
251 rt2UserData.getWriteBuffer().currentTcpPose = currentPose;
252 rt2UserData.commitWrite();
253
254 if (firstRun)
255 {
256 filtered_position = currentPose.block<3, 1>(0, 3);
257
258 firstRun = false;
259 for (size_t i = 0; i < targets.size(); ++i)
260 {
261 targets.at(i)->velocity = 0;
262 }
263 return;
264 }
265 else
266 {
267 filtered_position = (1 - pos_filter_factor) * filtered_position +
268 pos_filter_factor * currentPose.block<3, 1>(0, 3);
269 }
270
271 double deltaT = timeSinceLastIteration.toSecondsDouble();
272
273 Eigen::MatrixXf jacobi =
274 ik->getJacobianMatrix(tcp, VirtualRobot::IKSolver::CartesianSelection::All);
275
276 Eigen::VectorXf qvel(velocitySensors.size());
277 for (size_t i = 0; i < velocitySensors.size(); ++i)
278 {
279 qvel(i) = velocitySensors[i]->velocity;
280 }
281
282 filtered_qvel = (1 - vel_filter_factor) * filtered_qvel + vel_filter_factor * qvel;
283 Eigen::VectorXf tcptwist = jacobi * filtered_qvel;
284
285 rt2CtrlData.getWriteBuffer().currentPose = currentPose;
286 rt2CtrlData.getWriteBuffer().currentTwist = tcptwist;
287 rt2CtrlData.getWriteBuffer().deltaT = deltaT;
288 rt2CtrlData.getWriteBuffer().currentTime += deltaT;
289 rt2CtrlData.commitWrite();
290
291 rt2UserData.getWriteBuffer().currentTcpPose = currentPose;
292 rt2UserData.commitWrite();
293
294 Eigen::VectorXf targetVel = rtGetControlStruct().targetTSVel;
295 Eigen::Matrix4f targetPose = rtGetControlStruct().targetPose;
296
297 Eigen::VectorXf jointTargetVelocities = Eigen::VectorXf::Zero(targets.size());
298 if (started)
299 {
300 // targetVel = rtGetControlStruct().targetTSVel;
301 // targetPose = rtGetControlStruct().targetPose;
302
303 Eigen::Matrix3f diffMat =
304 targetPose.block<3, 3>(0, 0) * currentPose.block<3, 3>(0, 0).inverse();
305 Eigen::Vector3f errorRPY = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
306
307 Eigen::Vector6f rtTargetVel;
308 rtTargetVel.block<3, 1>(0, 0) =
309 KpF * (targetPose.block<3, 1>(0, 3) - currentPose.block<3, 1>(0, 3)) +
310 DpF * (-tcptwist.block<3, 1>(0, 0));
311 // rtTargetVel.block<3, 1>(0, 0) = KpF * (targetPose.block<3, 1>(0, 3) - currentPose.block<3, 1>(0, 3)) + DpF * (targetVel.block<3, 1>(0, 0) - tcptwist.block<3, 1>(0, 0));
312 rtTargetVel.block<3, 1>(3, 0) =
313 KoF * errorRPY + DoF * (targetVel.block<3, 1>(3, 0) - tcptwist.block<3, 1>(3, 0));
314 // rtTargetVel = targetVel;
315
316
317 float normLinearVelocity = rtTargetVel.block<3, 1>(0, 0).norm();
318 if (normLinearVelocity > cfg->maxLinearVel)
319 {
320 rtTargetVel.block<3, 1>(0, 0) =
321 cfg->maxLinearVel * rtTargetVel.block<3, 1>(0, 0) / normLinearVelocity;
322 }
323
324 float normAngularVelocity = rtTargetVel.block<3, 1>(3, 0).norm();
325 if (normAngularVelocity > cfg->maxAngularVel)
326 {
327 rtTargetVel.block<3, 1>(3, 0) =
328 cfg->maxAngularVel * rtTargetVel.block<3, 1>(3, 0) / normAngularVelocity;
329 }
330
331
332 // cartesian vel controller
333 // Eigen::Vector6f x;
334 // for (size_t i = 0; i < 6; i++)
335 // {
336 // x(i) = rtTargetVel(i);
337 // }
338
339 Eigen::VectorXf jnv = Eigen::VectorXf::Zero(tcpController->rns->getSize());
340 float jointLimitAvoidanceKp = rtGetControlStruct().avoidJointLimitsKp;
341 if (jointLimitAvoidanceKp > 0)
342 {
343 jnv += jointLimitAvoidanceKp * tcpController->calculateJointLimitAvoidance();
344 }
345 for (size_t i = 0; i < tcpController->rns->getSize(); i++)
346 {
347 jnv(i) += rtGetControlStruct().nullspaceJointVelocities.at(i);
348 }
349
350 // jointTargetVelocities = tcpController->calculate(x, jnv, VirtualRobot::IKSolver::CartesianSelection::All);
351 jointTargetVelocities =
352 calcIK(rtTargetVel, jnv, VirtualRobot::IKSolver::CartesianSelection::All);
353 // Eigen::VectorXf jointTargetVelocities = tcpController->calculate(x, jnv, VirtualRobot::IKSolver::CartesianSelection::All);
354 ARMARX_CHECK_EXPRESSION(!targets.empty());
355 ARMARX_CHECK_LESS(targets.size(), 1000);
356 }
357
358 for (size_t i = 0; i < targets.size(); ++i)
359 {
360 targets.at(i)->velocity = jointTargetVelocities(i);
361
362 if (!targets.at(i)->isValid() || fabs(targets.at(i)->velocity) > cfg->maxJointVelocity)
363 {
364 targets.at(i)->velocity = 0.0f;
365 }
366 }
367 rtDebugData.getWriteBuffer().targetJointVels = jointTargetVelocities;
368 rtDebugData.commitWrite();
369 }
370
371 void
372 NJointTSDMPController::learnDMPFromFiles(const Ice::StringSeq& fileNames, const Ice::Current&)
373 {
374 ARMARX_INFO << "Learning DMP ... ";
375
376 LockGuardType guard{controllerMutex};
377 dmpCtrl->learnDMPFromFiles(fileNames);
378 }
379
380 void
381 NJointTSDMPController::setSpeed(Ice::Double times, const Ice::Current&)
382 {
383 LockGuardType guard{controllerMutex};
384 dmpCtrl->setSpeed(times);
385 }
386
387 void
389 const Ice::DoubleSeq& viapoint,
390 const Ice::Current&)
391 {
392 LockGuardType guard{controllerMutex};
393 dmpCtrl->setViaPose(u, viapoint);
394 }
395
396 void
397 NJointTSDMPController::setTorqueKp(const StringFloatDictionary& torqueKp, const Ice::Current&)
398 {
400 for (size_t i = 0; i < tcpController->rns->getSize(); i++)
401 {
402 getWriterControlStruct().torqueKp.at(i) =
403 torqueKp.at(tcpController->rns->getNode(i)->getName());
404 }
406 }
407
408 void
410 const StringFloatDictionary& nullspaceJointVelocities,
411 const Ice::Current&)
412 {
414 for (size_t i = 0; i < tcpController->rns->getSize(); i++)
415 {
416 getWriterControlStruct().nullspaceJointVelocities.at(i) =
417 nullspaceJointVelocities.at(tcpController->rns->getNode(i)->getName());
418 }
420 }
421
422 void
424 Ice::Float avoidJointLimitsKp,
426 const Ice::Current&)
427 {
429 getWriterControlStruct().avoidJointLimitsKp = avoidJointLimitsKp;
430 getWriterControlStruct().mode = ModeFromIce(mode);
432 }
433
434 void
436 {
437 LockGuardType guard{controllerMutex};
438 ARMARX_INFO << "setting via points ";
439 dmpCtrl->removeAllViaPoints();
440 }
441
442 void
443 NJointTSDMPController::setGoals(const Ice::DoubleSeq& goals, const Ice::Current& ice)
444 {
445 LockGuardType guard{controllerMutex};
446 dmpCtrl->setGoalPoseVec(goals);
447 }
448
449 void
451 {
452 dmpCtrl->pauseController();
453 }
454
455 void
457 {
458 dmpCtrl->resumeController();
459 }
460
461 void
463 {
464 if (started)
465 {
466 ARMARX_INFO << "Cannot reset running DMP";
467 }
468 firstRun = true;
469 }
470
471 void
473 {
474 started = false;
475 }
476
477 std::string
479 {
480
481 return dmpCtrl->saveDMPToString();
482 }
483
484 std::vector<double>
485 NJointTSDMPController::createDMPFromString(const std::string& dmpString, const Ice::Current&)
486 {
487 dmpCtrl->loadDMPFromString(dmpString);
488 return dmpCtrl->dmpPtr->defaultGoal;
489 }
490
491 VirtualRobot::IKSolver::CartesianSelection
494 {
496 {
497 return VirtualRobot::IKSolver::CartesianSelection::Position;
498 }
500 {
501 return VirtualRobot::IKSolver::CartesianSelection::Orientation;
502 }
504 {
505 return VirtualRobot::IKSolver::CartesianSelection::All;
506 }
507 ARMARX_ERROR_S << "invalid mode " << mode;
508 return (VirtualRobot::IKSolver::CartesianSelection)0;
509 }
510
511 void
512 NJointTSDMPController::runDMP(const Ice::DoubleSeq& goals, double tau, const Ice::Current&)
513 {
514 ARMARX_INFO << "------dmp controller: " << VAROUT(goals);
515 firstRun = true;
516 while (firstRun)
517 {
518 usleep(100);
519 }
520 while (!rt2UserData.updateReadBuffer())
521 {
522 usleep(100);
523 }
524
525 Eigen::Matrix4f pose = rt2UserData.getReadBuffer().currentTcpPose;
526
527 LockGuardType guard{controllerMutex};
528 // Eigen::Matrix4f pose = tcp->getPoseInRootFrame();
529 dmpCtrl->prepareExecution(dmpCtrl->eigen4f2vec(pose), goals);
530 finished = false;
531
532 ARMARX_INFO << "run DMP";
533 started = true;
534 }
535
536 void
537 NJointTSDMPController::runDMPWithTime(const Ice::DoubleSeq& goals,
538 Ice::Double timeDuration,
539 const Ice::Current&)
540 {
541 firstRun = true;
542 while (firstRun)
543 {
544 usleep(100);
545 }
546 while (!rt2UserData.updateReadBuffer())
547 {
548 usleep(100);
549 }
550
551 Eigen::Matrix4f pose = rt2UserData.getReadBuffer().currentTcpPose;
552
553 LockGuardType guard{controllerMutex};
554 dmpCtrl->config.motionTimeDuration = timeDuration;
555 dmpCtrl->prepareExecution(dmpCtrl->eigen4f2vec(pose), goals);
556
557 finished = false;
558 started = true;
559 }
560
561 void
565
566 void
570
571 void
574 const DebugObserverInterfacePrx& debugObs)
575 {
576 std::string datafieldName = debugName;
577 StringVariantBaseMap datafields;
578 auto values = debugOutputData.getUpToDateReadBuffer().latestTargetVelocities;
579 for (auto& pair : values)
580 {
581 datafieldName = pair.first + "_" + debugName;
582 datafields[datafieldName] = new Variant(pair.second);
583 }
584
585 auto dmpTargets = debugOutputData.getUpToDateReadBuffer().dmpTargets;
586 for (auto& pair : dmpTargets)
587 {
588 datafieldName = pair.first + "_" + debugName;
589 datafields[datafieldName] = new Variant(pair.second);
590 }
591
592 auto currentPose = debugOutputData.getUpToDateReadBuffer().currentPose;
593 for (auto& pair : currentPose)
594 {
595 datafieldName = pair.first + "_" + debugName;
596 datafields[datafieldName] = new Variant(pair.second);
597 }
598
599 datafieldName = "canVal_" + debugName;
600 datafields[datafieldName] =
601 new Variant(debugOutputData.getUpToDateReadBuffer().currentCanVal);
602 datafieldName = "mpcFactor_" + debugName;
603 datafields[datafieldName] = new Variant(debugOutputData.getUpToDateReadBuffer().mpcFactor);
604 datafieldName = "error_" + debugName;
605 datafields[datafieldName] = new Variant(debugOutputData.getUpToDateReadBuffer().error);
606 datafieldName = "posError_" + debugName;
607 datafields[datafieldName] = new Variant(debugOutputData.getUpToDateReadBuffer().posError);
608 datafieldName = "oriError_" + debugName;
609 datafields[datafieldName] = new Variant(debugOutputData.getUpToDateReadBuffer().oriError);
610 datafieldName = "deltaT_" + debugName;
611 datafields[datafieldName] = new Variant(debugOutputData.getUpToDateReadBuffer().deltaT);
612
613
614 Eigen::VectorXf targetJoints = rtDebugData.getUpToDateReadBuffer().targetJointVels;
615 for (int i = 0; i < targetJoints.size(); ++i)
616 {
617 datafieldName = jointNames[i] + "_velocity";
618 datafields[datafieldName] = new Variant(targetJoints[i]);
619 }
620
621 datafieldName = "DMPController_" + debugName;
622 debugObs->setDebugChannel(datafieldName, datafields);
623 }
624
625 void
627 {
628 ARMARX_INFO << "init ...";
629 started = false;
630 runTask("NJointTSDMPController",
631 [&]
632 {
633 CycleUtil c(1);
634 getObjectScheduler()->waitForObjectStateMinimum(eManagedIceObjectStarted);
635 while (getState() == eManagedIceObjectStarted)
636 {
637 if (isControllerActive())
638 {
640 }
641 c.waitForCycleDuration();
642 }
643 });
644 }
645
646 void
651
652 void
653 NJointTSDMPController::setMPWeights(const DoubleSeqSeq& weights, const Ice::Current&)
654 {
655 dmpCtrl->setWeights(weights);
656 }
657
658 DoubleSeqSeq
660 {
661 DMP::DVec2d res = dmpCtrl->getWeights();
662 DoubleSeqSeq resvec;
663 for (size_t i = 0; i < res.size(); ++i)
664 {
665 std::vector<double> cvec;
666 for (size_t j = 0; j < res[i].size(); ++j)
667 {
668 cvec.push_back(res[i][j]);
669 }
670 resvec.push_back(cvec);
671 }
672
673 return resvec;
674 }
675
676 void
677 NJointTSDMPController::setLinearVelocityKd(Ice::Float kd, const Ice::Current&)
678 {
679 DpF = kd;
680 }
681
682 void
683 NJointTSDMPController::setLinearVelocityKp(Ice::Float kp, const Ice::Current&)
684 {
685 KpF = kp;
686 }
687
688 void
689 NJointTSDMPController::setAngularVelocityKd(Ice::Float kd, const Ice::Current&)
690 {
691 DoF = kd;
692 }
693
694 void
695 NJointTSDMPController::setAngularVelocityKp(Ice::Float kp, const Ice::Current&)
696 {
697 KoF = kp;
698 }
699
700} // namespace armarx::control::deprecated_njoint_mp_controller::task_space
#define VAROUT(x)
constexpr T c
Brief description of class JointControlTargetBase.
This util class helps with keeping a cycle time during a control cycle.
Definition CycleUtil.h:41
ArmarXObjectSchedulerPtr getObjectScheduler() const
int getState() const
Retrieve current state of the ManagedIceObject.
bool isControllerActive(const Ice::Current &=Ice::emptyCurrent) const final override
const SensorValueBase * useSensorValue(const std::string &sensorDeviceName) const
Get a const ptr to the given SensorDevice's SensorValue.
void runTask(const std::string &taskName, Task &&task)
Executes a given task in a separate thread from the Application ThreadPool.
const VirtualRobot::RobotPtr & useSynchronizedRtRobot(bool updateCollisionModel=false)
Requests a VirtualRobot for use in rtRun *.
const VirtualRobot::RobotPtr & rtGetRobot()
TODO make protected and use attorneys.
ControlTargetBase * useControlTarget(const std::string &deviceName, const std::string &controlMode)
Declares to calculate the ControlTarget for the given ControlDevice in the given ControlMode when rtR...
The SensorValueBase class.
const T * asA() const
The Variant class is described here: Variants.
Definition Variant.h:224
void setTorqueKp(const StringFloatDictionary &torqueKp, const Ice::Current &) override
virtual void onPublish(const SensorAndControl &, const DebugDrawerInterfacePrx &, const DebugObserverInterfacePrx &) override
void runDMP(const Ice::DoubleSeq &goals, Ice::Double tau, const Ice::Current &) override
void setNullspaceJointVelocities(const StringFloatDictionary &nullspaceJointVelocities, const Ice::Current &) override
Eigen::VectorXf calcIK(const Eigen::VectorXf &cartesianVel, const Eigen::VectorXf &nullspace, VirtualRobot::IKSolver::CartesianSelection mode)
void setControllerTarget(Ice::Float avoidJointLimitsKp, NJointTaskSpaceDMPControllerMode::CartesianSelection mode, const Ice::Current &) override
void setMPWeights(const DoubleSeqSeq &weights, const Ice::Current &) override
void setGoals(const Ice::DoubleSeq &goals, const Ice::Current &) override
void setLinearVelocityKd(Ice::Float kd, const Ice::Current &=Ice::emptyCurrent) override
void learnDMPFromFiles(const Ice::StringSeq &fileNames, const Ice::Current &) override
void setAngularVelocityKp(Ice::Float kp, const Ice::Current &=Ice::emptyCurrent) override
void rtPostDeactivateController() override
This function is called after the controller is deactivated.
void rtRun(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration) override
TODO make protected and use attorneys.
void setAngularVelocityKd(Ice::Float kd, const Ice::Current &=Ice::emptyCurrent) override
void setLinearVelocityKp(Ice::Float kp, const Ice::Current &=Ice::emptyCurrent) override
VirtualRobot::IKSolver::CartesianSelection ModeFromIce(const NJointTaskSpaceDMPControllerMode::CartesianSelection mode)
std::vector< double > createDMPFromString(const std::string &dmpString, const Ice::Current &) override
void setViaPoints(Ice::Double u, const Ice::DoubleSeq &viapoint, const Ice::Current &) override
NJointTSDMPController(const RobotUnitPtr &, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &)
void rtPreActivateController() override
This function is called before the controller is activated.
void runDMPWithTime(const Ice::DoubleSeq &goals, Ice::Double timeDuration, const Ice::Current &) override
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_CHECK_LESS(lhs, rhs)
This macro evaluates whether lhs is less (<) than rhs and if it turns out to be false it will throw a...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_ERROR_S
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:216
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
Matrix< float, 6, 1 > Vector6f
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
NJointControllerRegistration< NJointTSDMPController > registrationControllerNJointTSDMPController("NJointTSDMPController")
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugObserverInterface > DebugObserverInterfacePrx
std::map< std::string, VariantBasePtr > StringVariantBaseMap
IceUtil::Handle< class RobotUnit > RobotUnitPtr
Definition FTSensor.h:34
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugDrawerInterface > DebugDrawerInterfacePrx
detail::ControlThreadOutputBufferEntry SensorAndControl
double norm(const Point &a)
Definition point.hpp:102