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