DeprecatedNJointTSDMPController.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4
5#include <VirtualRobot/IK/DifferentialIK.h>
6#include <VirtualRobot/MathTools.h>
7#include <VirtualRobot/Nodes/RobotNode.h>
8#include <VirtualRobot/Robot.h>
9#include <VirtualRobot/RobotNodeSet.h>
10
13
20
22{
23
25 {
26 RTScopeTimer(const std::string& name) : start(armarx::rtNow()), name(name)
27 {
28 }
29
31 {
32 //float us = (armarx::rtNow() - start).toMicroSecondsDouble();
33 //ARMARX_IMPORTANT << name << " took " << us << " micro seconds";
34 }
35
36 IceUtil::Time start;
37 std::string name;
38 };
39
42
44 const RobotUnitPtr&,
45 const armarx::NJointControllerConfigPtr& config,
47 {
48 RTScopeTimer timer("DeprecatedNJointTSDMPController_constructor");
49 RT_TIMING_START(DeprecatedNJointTSDMPController_constructor)
51 cfg = DeprecatedNJointTaskSpaceDMPControllerConfigPtr::dynamicCast(config);
52 ARMARX_CHECK_EXPRESSION(!cfg->nodeSetName.empty());
53 VirtualRobot::RobotNodeSetPtr rns = rtGetRobot()->getRobotNodeSet(cfg->nodeSetName);
54 jointNames = rns->getNodeNames();
55 ARMARX_CHECK_EXPRESSION(rns) << cfg->nodeSetName;
56 for (size_t i = 0; i < rns->getSize(); ++i)
57 {
58 std::string jointName = rns->getNode(i)->getName();
59 ControlTargetBase* ct = useControlTarget(jointName, ControlModes::Velocity1DoF);
60 const SensorValueBase* sv = useSensorValue(jointName);
61 targets.push_back(ct->asA<ControlTarget1DoFActuatorVelocity>());
62
63 const SensorValue1DoFActuatorTorque* torqueSensor =
64 sv->asA<SensorValue1DoFActuatorTorque>();
65 const SensorValue1DoFActuatorVelocity* velocitySensor =
66 sv->asA<SensorValue1DoFActuatorVelocity>();
67 const SensorValue1DoFGravityTorque* gravityTorqueSensor =
68 sv->asA<SensorValue1DoFGravityTorque>();
69 const SensorValue1DoFActuatorPosition* positionSensor =
70 sv->asA<SensorValue1DoFActuatorPosition>();
71 if (!torqueSensor)
72 {
73 ARMARX_WARNING << "No Torque sensor available for " << jointName;
74 }
75 if (!gravityTorqueSensor)
76 {
77 ARMARX_WARNING << "No Gravity Torque sensor available for " << jointName;
78 }
79
80 torqueSensors.push_back(torqueSensor);
81 gravityTorqueSensors.push_back(gravityTorqueSensor);
82 velocitySensors.push_back(velocitySensor);
83 positionSensors.push_back(positionSensor);
84 };
85 forceSensor = useSensorValue(cfg->forceSensorName)->asA<SensorValueForceTorque>();
86
88 forceOffset.setZero();
89 filteredForce.setZero();
90 filteredForceInRoot.setZero();
91 forceThreshold.reinitAllBuffers(cfg->forceThreshold);
92 useForceStop = false;
93
94 if (not cfg->tcpName.empty())
95 {
96 ARMARX_INFO << "Custom TCP " << cfg->tcpName << " provided.";
97 }
98
99 tcp = cfg->tcpName.empty() ? rns->getTCP() : rtGetRobot()->getRobotNode(cfg->tcpName);
100
101 ARMARX_INFO << "Using TCP: " << tcp->getName();
102
103 refFrame = (cfg->frameName.empty()) ? rns->getRobot()->getRootNode()
104 : rtGetRobot()->getRobotNode(cfg->frameName);
105 ARMARX_CHECK_EXPRESSION(tcp) << cfg->tcpName;
106
107 // set tcp controller
108 tcpController.reset(new CartesianVelocityController(rns, tcp));
109 nodeSetName = cfg->nodeSetName;
110 torquePIDs.resize(tcpController->rns->getSize(), pidController());
111
112 ik.reset(new VirtualRobot::DifferentialIK(
113 rns, refFrame, VirtualRobot::JacobiProvider::eSVDDamped));
114
115
116 finished = false;
117 tsvmp::TaskSpaceDMPControllerConfig taskSpaceDMPConfig;
118 taskSpaceDMPConfig.motionTimeDuration = cfg->timeDuration;
119 taskSpaceDMPConfig.DMPKernelSize = cfg->kernelSize;
120 taskSpaceDMPConfig.DMPMode = cfg->dmpMode;
121 taskSpaceDMPConfig.DMPStyle = cfg->dmpStyle;
122 taskSpaceDMPConfig.DMPAmplitude = cfg->dmpAmplitude;
123 taskSpaceDMPConfig.phaseStopParas.goDist = cfg->phaseDist0;
124 taskSpaceDMPConfig.phaseStopParas.backDist = cfg->phaseDist1;
125 taskSpaceDMPConfig.phaseStopParas.Kpos = cfg->phaseKpPos;
126 taskSpaceDMPConfig.phaseStopParas.Dpos = 0;
127 taskSpaceDMPConfig.phaseStopParas.Kori = cfg->phaseKpOri;
128 taskSpaceDMPConfig.phaseStopParas.Dori = 0;
129 taskSpaceDMPConfig.phaseStopParas.mm2radi = cfg->posToOriRatio;
130 taskSpaceDMPConfig.phaseStopParas.maxValue = cfg->phaseL;
131 taskSpaceDMPConfig.phaseStopParas.slop = cfg->phaseK;
132
133 dmpCtrl.reset(new tsvmp::TaskSpaceDMPController("default", taskSpaceDMPConfig, false));
134
135 // initialize tcp position and orientation
136
137
138 RTToControllerData initSensorData;
139 initSensorData.deltaT = 0;
140 initSensorData.currentTime = 0;
141 initSensorData.currentPose.setZero();
142 initSensorData.currentTwist.setZero();
143 rt2CtrlData.reinitAllBuffers(initSensorData);
144
145 targetVels.setZero(6);
147 initData.targetTSVel.setZero(6);
148 initData.targetPose = refFrame->toLocalCoordinateSystem(tcp->getGlobalPose());
149 initData.nullspaceJointVelocities.resize(tcpController->rns->getSize(), 0);
150 initData.torqueKp.resize(tcpController->rns->getSize(), 0);
151 initData.torqueKd.resize(tcpController->rns->getSize(), 0);
152 initData.mode = ModeFromIce(cfg->mode);
153 reinitTripleBuffer(initData);
154
155 debugName = cfg->debugName;
156
157 KpF = cfg->Kp_LinearVel;
158 KoF = cfg->Kp_AngularVel;
159 DpF = cfg->Kd_LinearVel;
160 DoF = cfg->Kd_AngularVel;
161
162 filtered_qvel.setZero(targets.size());
163 vel_filter_factor = cfg->vel_filter;
164
165 filtered_position.setZero(3);
166 pos_filter_factor = cfg->pos_filter;
167
168 // jlhigh = rns->getNode("..")->getJointLimitHi();
169 // jllow = rns->getNode("")->getJointLimitLo();
170 firstRun = true;
171
172 jointLowLimits.setZero(targets.size());
173 jointHighLimits.setZero(targets.size());
174 for (size_t i = 0; i < rns->getSize(); i++)
175 {
176 VirtualRobot::RobotNodePtr rn = rns->getAllRobotNodes().at(i);
177
178 jointLowLimits(i) = rn->getJointLimitLo();
179 jointHighLimits(i) = rn->getJointLimitHi();
180 }
181
182 started = false;
183
184 RTToUserData initInterfaceData;
185 initInterfaceData.currentTcpPose = Eigen::Matrix4f::Identity();
186 rt2UserData.reinitAllBuffers(initInterfaceData);
187 RT_TIMING_END(DeprecatedNJointTSDMPController_constructor)
188 }
189
190 std::string
192 {
193 return "DeprecatedNJointTSDMPController";
194 }
195
196 void
198 {
199 RTScopeTimer timer("controllerRun");
200 if (!started)
201 {
202 return;
203 }
204
205 if (!rt2CtrlData.updateReadBuffer() || !dmpCtrl)
206 {
207 return;
208 }
209
210 double deltaT = rt2CtrlData.getReadBuffer().deltaT;
211 Eigen::Matrix4f currentPose = rt2CtrlData.getReadBuffer().currentPose;
212 Eigen::VectorXf currentTwist = rt2CtrlData.getReadBuffer().currentTwist;
213
214 LockGuardType guard{controllerMutex};
215 dmpCtrl->flow(deltaT, currentPose, currentTwist);
216
217 if (dmpCtrl->canVal < 1e-8)
218 {
219 finished = true;
220 }
221 targetVels = dmpCtrl->getTargetVelocity();
222 targetPose = dmpCtrl->getTargetPoseMat();
223 std::vector<double> targetState = dmpCtrl->getTargetPose();
224
225 debugOutputData.getWriteBuffer().latestTargetVelocities["x_vel"] = targetVels(0);
226 debugOutputData.getWriteBuffer().latestTargetVelocities["y_vel"] = targetVels(1);
227 debugOutputData.getWriteBuffer().latestTargetVelocities["z_vel"] = targetVels(2);
228 debugOutputData.getWriteBuffer().latestTargetVelocities["roll_vel"] = targetVels(3);
229 debugOutputData.getWriteBuffer().latestTargetVelocities["pitch_vel"] = targetVels(4);
230 debugOutputData.getWriteBuffer().latestTargetVelocities["yaw_vel"] = targetVels(5);
231 debugOutputData.getWriteBuffer().dmpTargets["dmp_x"] = targetState[0];
232 debugOutputData.getWriteBuffer().dmpTargets["dmp_y"] = targetState[1];
233 debugOutputData.getWriteBuffer().dmpTargets["dmp_z"] = targetState[2];
234 debugOutputData.getWriteBuffer().dmpTargets["dmp_qw"] = targetState[3];
235 debugOutputData.getWriteBuffer().dmpTargets["dmp_qx"] = targetState[4];
236 debugOutputData.getWriteBuffer().dmpTargets["dmp_qy"] = targetState[5];
237 debugOutputData.getWriteBuffer().dmpTargets["dmp_qz"] = targetState[6];
238 debugOutputData.getWriteBuffer().currentPose["currentPose_x"] = currentPose(0, 3);
239 debugOutputData.getWriteBuffer().currentPose["currentPose_y"] = currentPose(1, 3);
240 debugOutputData.getWriteBuffer().currentPose["currentPose_z"] = currentPose(2, 3);
241
242 VirtualRobot::MathTools::Quaternion currentQ =
243 VirtualRobot::MathTools::eigen4f2quat(currentPose);
244 debugOutputData.getWriteBuffer().currentPose["currentPose_qw"] = currentQ.w;
245 debugOutputData.getWriteBuffer().currentPose["currentPose_qx"] = currentQ.x;
246 debugOutputData.getWriteBuffer().currentPose["currentPose_qy"] = currentQ.y;
247 debugOutputData.getWriteBuffer().currentPose["currentPose_qz"] = currentQ.z;
248 debugOutputData.getWriteBuffer().currentCanVal = dmpCtrl->debugData.canVal;
249 debugOutputData.getWriteBuffer().mpcFactor = dmpCtrl->debugData.mpcFactor;
250 debugOutputData.getWriteBuffer().error = dmpCtrl->debugData.poseError;
251 debugOutputData.getWriteBuffer().posError = dmpCtrl->debugData.posiError;
252 debugOutputData.getWriteBuffer().oriError = dmpCtrl->debugData.oriError;
253 debugOutputData.getWriteBuffer().deltaT = deltaT;
254
255 debugOutputData.commitWrite();
256
257 getWriterControlStruct().targetTSVel = targetVels;
258 getWriterControlStruct().targetPose = targetPose;
260 }
261
262 Eigen::VectorXf
263 DeprecatedNJointTSDMPController::calcIK(const Eigen::VectorXf& cartesianVel,
264 const Eigen::VectorXf& nullspaceVel,
265 VirtualRobot::IKSolver::CartesianSelection mode)
266 {
267 RTScopeTimer timer("calcIK");
268 Eigen::MatrixXf jacobi = ik->getJacobianMatrix(tcp, mode);
269
270 Eigen::FullPivLU<Eigen::MatrixXf> lu_decomp(jacobi);
271
272 Eigen::MatrixXf nullspace = lu_decomp.kernel();
273 Eigen::VectorXf nsv = Eigen::VectorXf::Zero(nullspace.rows());
274 for (int i = 0; i < nullspace.cols(); i++)
275 {
276 float squaredNorm = nullspace.col(i).squaredNorm();
277 // Prevent division by zero
278 if (squaredNorm > 1.0e-32f)
279 {
280 nsv += nullspace.col(i) * nullspace.col(i).dot(nullspaceVel) /
281 nullspace.col(i).squaredNorm();
282 }
283 }
284
285 Eigen::MatrixXf inv =
286 ik->computePseudoInverseJacobianMatrix(jacobi, ik->getJacobiRegularization(mode));
287 // ARMARX_INFO << "inv: " << inv;
288 Eigen::VectorXf jointVel = inv * cartesianVel;
289 // jointVel += nsv;
290 return jointVel;
291 }
292
293 void
294 DeprecatedNJointTSDMPController::rtRun(const IceUtil::Time& sensorValuesTimestamp,
295 const IceUtil::Time& timeSinceLastIteration)
296 {
297 // RT_TIMING_START(DeprecatedNJointTSDMPController_rtRun)
298 Eigen::Matrix4f currentPose = refFrame->toLocalCoordinateSystem(tcp->getGlobalPose());
299 rt2UserData.getWriteBuffer().currentTcpPose = currentPose;
300 rt2UserData.commitWrite();
301
302 if (firstRun)
303 {
304 filtered_position = currentPose.block<3, 1>(0, 3);
305
306 firstRun = false;
307 for (size_t i = 0; i < targets.size(); ++i)
308 {
309 targets.at(i)->velocity = 0;
310 }
311 return;
312 }
313 else
314 {
315 filtered_position = (1 - pos_filter_factor) * filtered_position +
316 pos_filter_factor * currentPose.block<3, 1>(0, 3);
317 if (not started)
318 {
319 forceOffset =
320 (1 - cfg->forceFilter) * forceOffset + cfg->forceFilter * forceSensor->force;
321 timeForCalibration = timeForCalibration + timeSinceLastIteration.toSecondsDouble();
322 }
323 if (started and useForceStop)
324 {
325 /* handle force stop */
326 filteredForce = (1 - cfg->forceFilter) * filteredForce +
327 cfg->forceFilter * (forceSensor->force - forceOffset);
328
329 for (size_t i = 0; i < 3; ++i)
330 {
331 if (fabs(filteredForce(i)) > cfg->forceDeadZone)
332 {
333 filteredForce(i) -=
334 (filteredForce(i) / fabs(filteredForce(i))) * cfg->forceDeadZone;
335 }
336 else
337 {
338 filteredForce(i) = 0;
339 }
340 }
341 Eigen::Matrix4f forceFrameInRoot =
342 rtGetRobot()->getRobotNode(cfg->forceFrameName)->getPoseInRootFrame();
343 filteredForceInRoot = forceFrameInRoot.block<3, 3>(0, 0) * filteredForce;
344
345 for (size_t i = 0; i < 3; ++i)
346 {
347 if (fabs(filteredForceInRoot[i]) > forceThreshold.getUpToDateReadBuffer()[i])
348 {
349 started = false;
350 break;
351 }
352 }
353 }
354 }
355
356 double deltaT = timeSinceLastIteration.toSecondsDouble();
357
358 Eigen::MatrixXf jacobi =
359 ik->getJacobianMatrix(tcp, VirtualRobot::IKSolver::CartesianSelection::All);
360
361 Eigen::VectorXf qvel(velocitySensors.size());
362 for (size_t i = 0; i < velocitySensors.size(); ++i)
363 {
364 qvel(i) = velocitySensors[i]->velocity;
365 }
366
367 filtered_qvel = (1 - vel_filter_factor) * filtered_qvel + vel_filter_factor * qvel;
368 Eigen::VectorXf tcptwist = jacobi * filtered_qvel;
369
370 rt2CtrlData.getWriteBuffer().currentPose = currentPose;
371 rt2CtrlData.getWriteBuffer().currentTwist = tcptwist;
372 rt2CtrlData.getWriteBuffer().deltaT = deltaT;
373 rt2CtrlData.getWriteBuffer().currentTime += deltaT;
374 rt2CtrlData.commitWrite();
375
376 rt2UserData.getWriteBuffer().currentTcpPose = currentPose;
377 rt2UserData.commitWrite();
378
379 Eigen::VectorXf targetVel = rtGetControlStruct().targetTSVel;
380 Eigen::Matrix4f targetPose = rtGetControlStruct().targetPose;
381
382 Eigen::VectorXf jointTargetVelocities = Eigen::VectorXf::Zero(targets.size());
383 if (started)
384 {
385 // targetVel = rtGetControlStruct().targetTSVel;
386 // targetPose = rtGetControlStruct().targetPose;
387
388 Eigen::Matrix3f diffMat =
389 targetPose.block<3, 3>(0, 0) * currentPose.block<3, 3>(0, 0).inverse();
390 Eigen::Vector3f errorRPY = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
391
392 Eigen::Vector6f rtTargetVel;
393 rtTargetVel.block<3, 1>(0, 0) =
394 KpF * (targetPose.block<3, 1>(0, 3) - currentPose.block<3, 1>(0, 3)) +
395 DpF * (-tcptwist.block<3, 1>(0, 0));
396 // 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));
397 rtTargetVel.block<3, 1>(3, 0) =
398 KoF * errorRPY + DoF * (targetVel.block<3, 1>(3, 0) - tcptwist.block<3, 1>(3, 0));
399 // rtTargetVel = targetVel;
400
401
402 float normLinearVelocity = rtTargetVel.block<3, 1>(0, 0).norm();
403 if (normLinearVelocity > cfg->maxLinearVel)
404 {
405 rtTargetVel.block<3, 1>(0, 0) =
406 cfg->maxLinearVel * rtTargetVel.block<3, 1>(0, 0) / normLinearVelocity;
407 }
408
409 float normAngularVelocity = rtTargetVel.block<3, 1>(3, 0).norm();
410 if (normAngularVelocity > cfg->maxAngularVel)
411 {
412 rtTargetVel.block<3, 1>(3, 0) =
413 cfg->maxAngularVel * rtTargetVel.block<3, 1>(3, 0) / normAngularVelocity;
414 }
415
416
417 // cartesian vel controller
418 // Eigen::Vector6f x;
419 // for (size_t i = 0; i < 6; i++)
420 // {
421 // x(i) = rtTargetVel(i);
422 // }
423
424 Eigen::VectorXf jnv = Eigen::VectorXf::Zero(tcpController->rns->getSize());
425 float jointLimitAvoidanceKp = rtGetControlStruct().avoidJointLimitsKp;
426 if (jointLimitAvoidanceKp > 0)
427 {
428 jnv += jointLimitAvoidanceKp * tcpController->calculateJointLimitAvoidance();
429 }
430 for (size_t i = 0; i < tcpController->rns->getSize(); i++)
431 {
432 jnv(i) += rtGetControlStruct().nullspaceJointVelocities.at(i);
433 }
434
435 // jointTargetVelocities = tcpController->calculate(x, jnv, VirtualRobot::IKSolver::CartesianSelection::All);
436 jointTargetVelocities =
437 calcIK(rtTargetVel, jnv, VirtualRobot::IKSolver::CartesianSelection::All);
438 // Eigen::VectorXf jointTargetVelocities = tcpController->calculate(x, jnv, VirtualRobot::IKSolver::CartesianSelection::All);
439 ARMARX_CHECK_EXPRESSION(!targets.empty());
440 ARMARX_CHECK_LESS(targets.size(), 1000);
441 }
442
443
444 // If the controller is stopped, set the velocity to 0
445 // and skip the rest of the loop. This ensures that no velocity from the controller
446 // is sent to the targets when the controller is stopped.
447 if (stopped.load())
448 {
449 // ARMARX_INFO << deactivateSpam(1.) << "Controller is stopped. Setting velocity to 0";
450 std::for_each(
451 targets.begin(), targets.end(), [](auto* target) { target->velocity = 0; });
452 }
453 else
454 {
455 for (size_t i = 0; i < targets.size(); ++i)
456 {
457 targets.at(i)->velocity = jointTargetVelocities(i);
458
459 if (!targets.at(i)->isValid() ||
460 fabs(targets.at(i)->velocity) > cfg->maxJointVelocity)
461 {
462 targets.at(i)->velocity = 0.0f;
463 }
464 }
465 }
466 rtDebugData.getWriteBuffer().targetJointVels = jointTargetVelocities;
467 rtDebugData.commitWrite();
468 // RT_TIMING_CEND(DeprecatedNJointTSDMPController_rtRun, 0.1)
469 }
470
471 void
473 const Ice::Current&)
474 {
475 RTScopeTimer timer("learnDMPFromFiles");
476 ARMARX_INFO << "Learning DMP ... ";
477
478 LockGuardType guard{controllerMutex};
479 dmpCtrl->learnDMPFromFiles(fileNames);
480 }
481
482 void
483 DeprecatedNJointTSDMPController::setSpeed(Ice::Double times, const Ice::Current&)
484 {
485 RTScopeTimer timer("setSpeed");
486 LockGuardType guard{controllerMutex};
487 dmpCtrl->setSpeed(times);
488 }
489
490 void
492 const Ice::DoubleSeq& viapoint,
493 const Ice::Current&)
494 {
495 RTScopeTimer timer("setViaPoints");
496 LockGuardType guard{controllerMutex};
497 dmpCtrl->setViaPose(u, viapoint);
498 }
499
500 void
501 DeprecatedNJointTSDMPController::setTorqueKp(const StringFloatDictionary& torqueKp,
502 const Ice::Current&)
503 {
504 RTScopeTimer timer("setTorqueKp");
506 for (size_t i = 0; i < tcpController->rns->getSize(); i++)
507 {
508 getWriterControlStruct().torqueKp.at(i) =
509 torqueKp.at(tcpController->rns->getNode(i)->getName());
510 }
512 }
513
514 void
516 const StringFloatDictionary& nullspaceJointVelocities,
517 const Ice::Current&)
518 {
519 RTScopeTimer timer("setNullspaceJointVelocities");
521 for (size_t i = 0; i < tcpController->rns->getSize(); i++)
522 {
523 getWriterControlStruct().nullspaceJointVelocities.at(i) =
524 nullspaceJointVelocities.at(tcpController->rns->getNode(i)->getName());
525 }
527 }
528
529 void
531 Ice::Float avoidJointLimitsKp,
533 const Ice::Current&)
534 {
535 RTScopeTimer timer("setControllerTarget");
537 getWriterControlStruct().avoidJointLimitsKp = avoidJointLimitsKp;
538 getWriterControlStruct().mode = ModeFromIce(mode);
540 }
541
542 void
544 {
545 RTScopeTimer timer("removeAllViaPoints");
546 LockGuardType guard{controllerMutex};
547 ARMARX_INFO << "setting via points ";
548 dmpCtrl->removeAllViaPoints();
549 }
550
551 void
552 DeprecatedNJointTSDMPController::setGoals(const Ice::DoubleSeq& goals, const Ice::Current& ice)
553 {
554 RTScopeTimer timer("setGoals");
555 LockGuardType guard{controllerMutex};
556 dmpCtrl->setGoalPoseVec(goals);
557 }
558
559 void
561 {
562 RTScopeTimer timer("pauseDMP");
563 dmpCtrl->pauseController();
564 }
565
566 void
568 {
569 RTScopeTimer timer("resumeDMP");
570 dmpCtrl->resumeController();
571 }
572
573 void
575 {
576 RTScopeTimer timer("resetDMP");
577 if (started)
578 {
579 ARMARX_INFO << "Cannot reset running DMP";
580 }
581 firstRun = true;
582 }
583
584 void
586 {
587 RTScopeTimer timer("stopDMP");
588 started = false;
589 stopped = true;
590
591 // If the NJoint controller is stopped, the underlying controller should be stopped as well.
592 // Note: resumeDMP() does not work if the controller is stopped.
593 pauseDMP(c);
594 }
595
596 std::string
598 {
599 RTScopeTimer timer("getDMPAsString");
600 return dmpCtrl->saveDMPToString();
601 }
602
603 std::vector<double>
605 const Ice::Current&)
606 {
607 RTScopeTimer timer("createDMPFromString");
608 dmpCtrl->loadDMPFromString(dmpString);
609 return dmpCtrl->dmpPtr->defaultGoal;
610 }
611
612 VirtualRobot::IKSolver::CartesianSelection
615 {
616 RTScopeTimer timer("ModeFromIce");
618 {
619 return VirtualRobot::IKSolver::CartesianSelection::Position;
620 }
622 {
623 return VirtualRobot::IKSolver::CartesianSelection::Orientation;
624 }
626 {
627 return VirtualRobot::IKSolver::CartesianSelection::All;
628 }
629 ARMARX_ERROR_S << "invalid mode " << mode;
630 return (VirtualRobot::IKSolver::CartesianSelection)0;
631 }
632
633 void
634 DeprecatedNJointTSDMPController::runDMP(const Ice::DoubleSeq& goals,
635 double tau,
636 const Ice::Current&)
637 {
638 RTScopeTimer timer("runDMP");
639 ARMARX_INFO << "------dmp controller: " << VAROUT(goals);
640 firstRun = true;
641
642 stopped = false;
643 timeForCalibration = 0;
644 while (firstRun || timeForCalibration < cfg->waitTimeForCalibration)
645 {
646 if (stopped.load())
647 {
648 ARMARX_WARNING << "StopDMP has been prematurely called; aborting runDMP";
649 return;
650 }
651 usleep(100);
652 }
653 while (!rt2UserData.updateReadBuffer())
654 {
655 usleep(100);
656 }
657
658 Eigen::Matrix4f pose = rt2UserData.getReadBuffer().currentTcpPose;
659
660 LockGuardType guard{controllerMutex};
661 // Eigen::Matrix4f pose = tcp->getPoseInRootFrame();
662 dmpCtrl->prepareExecution(dmpCtrl->eigen4f2vec(pose), goals);
663 dmpCtrl->resumeController();
664
665 finished = false;
666
667 ARMARX_INFO << "run DMP";
668 started = true;
669 }
670
671 void
673 Ice::Double timeDuration,
674 const Ice::Current&)
675 {
676 RTScopeTimer timer("runDMPWithTime");
677 firstRun = true;
678 stopped = false;
679
680 while (firstRun || timeForCalibration < cfg->waitTimeForCalibration)
681 {
682 if (stopped.load())
683 {
684 ARMARX_WARNING << "StopDMP has been prematurely called; aborting runDMP";
685 return;
686 }
687 usleep(100);
688 }
689 while (!rt2UserData.updateReadBuffer())
690 {
691 usleep(100);
692 }
693
694 Eigen::Matrix4f pose = rt2UserData.getReadBuffer().currentTcpPose;
695
696 LockGuardType guard{controllerMutex};
697 dmpCtrl->config.motionTimeDuration = timeDuration;
698 dmpCtrl->prepareExecution(dmpCtrl->eigen4f2vec(pose), goals);
699 dmpCtrl->resumeController();
700
701 finished = false;
702 started = true;
703 }
704
705 void
709
710 void
712 {
713 ARMARX_INFO << "controller has been deactivated";
714 }
715
716 void
719 const DebugObserverInterfacePrx& debugObs)
720 {
721 RTScopeTimer timer("onPublish");
722 std::string datafieldName = debugName;
723 StringVariantBaseMap datafields;
724 auto values = debugOutputData.getUpToDateReadBuffer().latestTargetVelocities;
725 for (auto& pair : values)
726 {
727 datafieldName = pair.first + "_" + debugName;
728 datafields[datafieldName] = new Variant(pair.second);
729 }
730
731 auto dmpTargets = debugOutputData.getUpToDateReadBuffer().dmpTargets;
732 for (auto& pair : dmpTargets)
733 {
734 datafieldName = pair.first + "_" + debugName;
735 datafields[datafieldName] = new Variant(pair.second);
736 }
737
738 auto currentPose = debugOutputData.getUpToDateReadBuffer().currentPose;
739 for (auto& pair : currentPose)
740 {
741 datafieldName = pair.first + "_" + debugName;
742 datafields[datafieldName] = new Variant(pair.second);
743 }
744
745 datafieldName = "canVal_" + debugName;
746 datafields[datafieldName] =
747 new Variant(debugOutputData.getUpToDateReadBuffer().currentCanVal);
748 datafieldName = "mpcFactor_" + debugName;
749 datafields[datafieldName] = new Variant(debugOutputData.getUpToDateReadBuffer().mpcFactor);
750 datafieldName = "error_" + debugName;
751 datafields[datafieldName] = new Variant(debugOutputData.getUpToDateReadBuffer().error);
752 datafieldName = "posError_" + debugName;
753 datafields[datafieldName] = new Variant(debugOutputData.getUpToDateReadBuffer().posError);
754 datafieldName = "oriError_" + debugName;
755 datafields[datafieldName] = new Variant(debugOutputData.getUpToDateReadBuffer().oriError);
756 datafieldName = "deltaT_" + debugName;
757 datafields[datafieldName] = new Variant(debugOutputData.getUpToDateReadBuffer().deltaT);
759 << "Error: " << debugOutputData.getUpToDateReadBuffer().error
760 << "\nPosition Error: " << debugOutputData.getUpToDateReadBuffer().posError
761 << "\nOrientation Error: "
762 << debugOutputData.getUpToDateReadBuffer().oriError;
763
764 Eigen::VectorXf targetJoints = rtDebugData.getUpToDateReadBuffer().targetJointVels;
765 for (int i = 0; i < targetJoints.size(); ++i)
766 {
767 datafieldName = jointNames[i] + "_velocity";
768 datafields[datafieldName] = new Variant(targetJoints[i]);
769 }
770
771 datafieldName = "DMPController_" + debugName;
772 debugObs->setDebugChannel(datafieldName, datafields);
773 }
774
775 void
777 {
778 RTScopeTimer timer("onInitNJointController");
779 ARMARX_INFO << "init ...";
780 started = false;
781 runTask("DeprecatedNJointTSDMPController",
782 [&]
783 {
784 CycleUtil c(1);
785 getObjectScheduler()->waitForObjectStateMinimum(eManagedIceObjectStarted);
786 while (getState() == eManagedIceObjectStarted)
787 {
788 if (isControllerActive())
789 {
791 }
792 c.waitForCycleDuration();
793 }
794 });
795 }
796
797 void
802
803 void
804 DeprecatedNJointTSDMPController::setMPWeights(const DoubleSeqSeq& weights, const Ice::Current&)
805 {
806 RTScopeTimer timer("setMPWeights");
807 dmpCtrl->setWeights(weights);
808 }
809
810 DoubleSeqSeq
812 {
813 RTScopeTimer timer("getMPWeights");
814 DMP::DVec2d res = dmpCtrl->getWeights();
815 DoubleSeqSeq resvec;
816 for (size_t i = 0; i < res.size(); ++i)
817 {
818 std::vector<double> cvec;
819 for (size_t j = 0; j < res[i].size(); ++j)
820 {
821 cvec.push_back(res[i][j]);
822 }
823 resvec.push_back(cvec);
824 }
825
826 return resvec;
827 }
828
829 void
831 {
832 DpF = kd;
833 }
834
835 void
837 {
838 KpF = kp;
839 }
840
841 void
843 {
844 DoF = kd;
845 }
846
847 void
849 {
850 KoF = kp;
851 }
852
853} // namespace armarx::control::deprecated_njoint_mp_controller::task_space
#define RT_TIMING_START(name)
Definition RtTiming.h:50
#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
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition Logging.cpp:99
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 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.
VirtualRobot::IKSolver::CartesianSelection ModeFromIce(const NJointTaskSpaceDMPControllerMode::CartesianSelection mode)
std::vector< double > createDMPFromString(const std::string &dmpString, const Ice::Current &) override
DeprecatedNJointTSDMPController(const RobotUnitPtr &, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &)
void setViaPoints(Ice::Double u, const Ice::DoubleSeq &viapoint, const Ice::Current &) override
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
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:185
#define RT_TIMING_END(name)
Prints duration.
Definition RtTiming.h:57
Matrix< float, 6, 1 > Vector6f
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
NJointControllerRegistration< DeprecatedNJointTSDMPController > registrationControllerDeprecatedNJointTSDMPController("DeprecatedNJointTSDMPController")
This file offers overloads of toIce() and fromIce() functions for STL container types.
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugObserverInterface > DebugObserverInterfacePrx
std::map< std::string, VariantBasePtr > StringVariantBaseMap
IceUtil::Time rtNow()
Definition RtTiming.h:40
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
#define ARMARX_TRACE
Definition trace.h:75