KeypointsMPController.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package TaskSpaceActiveImpedanceControl::ArmarXObjects::NJointTaskSpaceImpedanceController
17 * @author zhou ( you dot zhou at kit dot edu )
18 * @date 2018
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
23
24#include <SimoxUtility/math/compare/is_equal.h>
25#include <SimoxUtility/math/convert/mat4f_to_pos.h>
26#include <SimoxUtility/math/convert/mat4f_to_quat.h>
27#include <VirtualRobot/MathTools.h>
28
31
33{
34 NJointControllerRegistration<KeypointMPController>
36
38 const NJointControllerConfigPtr& config,
40 {
41 ARMARX_INFO << "creating task-space admittance controller";
42 KeypointMPControllerConfigPtr cfg = KeypointMPControllerConfigPtr::dynamicCast(config);
43
45 ARMARX_CHECK_EXPRESSION(robotUnit);
46 ARMARX_CHECK_EXPRESSION(!cfg->nodeSetName.empty());
48 kinematicChainName = cfg->nodeSetName;
49
50 VirtualRobot::RobotNodeSetPtr rns = rtGetRobot()->getRobotNodeSet(cfg->nodeSetName);
51 ARMARX_CHECK_EXPRESSION(rns) << cfg->nodeSetName;
52
53 jointNames.clear();
54 for (size_t i = 0; i < rns->getSize(); ++i)
55 {
56 std::string jointName = rns->getNode(i)->getName();
57 jointNames.push_back(jointName);
58 ControlTargetBase* ct = useControlTarget(jointName, ControlModes::Torque1DoF);
60 const SensorValueBase* sv = useSensorValue(jointName);
62 auto casted_ct = ct->asA<ControlTarget1DoFActuatorTorque>();
63 ARMARX_CHECK_EXPRESSION(casted_ct);
64 targets.push_back(casted_ct);
65
66 const SensorValue1DoFActuatorTorque* torqueSensor =
67 sv->asA<SensorValue1DoFActuatorTorque>();
68 const SensorValue1DoFActuatorVelocity* velocitySensor =
69 sv->asA<SensorValue1DoFActuatorVelocity>();
70 const SensorValue1DoFActuatorPosition* positionSensor =
71 sv->asA<SensorValue1DoFActuatorPosition>();
72 if (!torqueSensor)
73 {
74 ARMARX_WARNING << "No Torque sensor available for " << jointName;
75 }
76 if (!velocitySensor)
77 {
78 ARMARX_WARNING << "No velocity sensor available for " << jointName;
79 }
80 if (!positionSensor)
81 {
82 ARMARX_WARNING << "No position sensor available for " << jointName;
83 }
84
85 torqueSensors.push_back(torqueSensor);
86 velocitySensors.push_back(velocitySensor);
87 positionSensors.push_back(positionSensor);
88 };
89 controller.initialize(rns);
90
91 ftsensor.initialize(rns, robotUnit, cfg->controlParamJsonFile);
92
93 /// mp related
94 // pointVMP.reset(new mplib::representation::vmp::PrincipalComponentVMP());
95
96 mplib::factories::VMPFactory mpfactory;
97 mpfactory.addConfig("kernelSize", 100);
98 mplib::representation::VMPType vmp_type =
99 mplib::representation::VMPType::PrincipalComponent;
100 std::shared_ptr<mplib::representation::AbstractMovementPrimitive> vmp =
101 mpfactory.createMP(vmp_type);
102 pointVMP =
103 std::dynamic_pointer_cast<mplib::representation::vmp::PrincipalComponentVMP>(vmp);
104
105 /// buffer related
106 common::FTSensor::FTBufferData ftData;
107 ftData.forceBaseline.setZero();
108 ftData.torqueBaseline.setZero();
109 ftData.enableTCPGravityCompensation = cfg->enableTCPGravityCompensation;
110 ftData.tcpMass = cfg->tcpMass;
111 ftData.tcpCoMInFTSensorFrame = cfg->tcpCoMInForceSensorFrame;
112 ftSensorBuffer.reinitAllBuffers(ftData);
113
114 law::TaskspaceKeypointsAdmittanceController::Config configData;
115 configData.kpImpedance = cfg->kpImpedance;
116 configData.kdImpedance = cfg->kdImpedance;
117 configData.kpAdmittance = cfg->kpAdmittance;
118 configData.kdAdmittance = cfg->kdAdmittance;
119 configData.kmAdmittance = cfg->kmAdmittance;
120
121 configData.kpNullspaceTorque = cfg->kpNullspaceTorque;
122 configData.kdNullspaceTorque = cfg->kdNullspaceTorque;
123
124 configData.currentForceTorque.setZero();
125 configData.desiredTCPPose = Eigen::Matrix4f::Identity();
126 configData.desiredTCPTwist.setZero();
127 configData.desiredNullspaceJointAngles = cfg->desiredNullspaceJointAngles;
128
129 configData.torqueLimit = cfg->torqueLimit;
130 configData.qvelFilter = cfg->qvelFilter;
131
132 ARMARX_IMPORTANT << VAROUT(cfg->numKeypoints);
133 ARMARX_CHECK_EQUAL(cfg->initialKeypointPosition.size(), cfg->numKeypoints * 3);
134 ARMARX_CHECK_EQUAL(cfg->pointCtrlMask.size(), cfg->numKeypoints * 3);
135 configData.numPoints = cfg->numKeypoints;
136 // configData.keypointStiffness = cfg->keypointStiffness;
137 configData.keypointKp = cfg->keypointKp;
138 configData.keypointKi = cfg->keypointKi;
139 configData.keypointKd = cfg->keypointKd;
140 configData.maxControlValue = cfg->maxControlValue;
141 configData.maxDerivation = cfg->maxDerivation;
142
143 configData.pointCtrlMask = cfg->pointCtrlMask;
144 configData.currentKeypointPosition = cfg->initialKeypointPosition;
145 configData.filteredKeypointPosition = cfg->initialKeypointPosition;
146 configData.desiredKeypointPosition = cfg->initialKeypointPosition;
147 configData.isRigid = cfg->isRigid;
148 configData.fixedTranslation.setZero(cfg->numKeypoints * 3);
149 reinitTripleBuffer(configData);
150
151 numPoints = cfg->numKeypoints;
152 initialStateEigen = cfg->initialKeypointPosition;
153 controller.filterCoeff = cfg->filterCoeff;
154 controller.s.filteredKeypointPosition = cfg->initialKeypointPosition;
155 controller.s.isRigid = cfg->isRigid;
156 controller.s.fixedTranslation.setZero(cfg->numKeypoints * 3);
157 controller.s.currentKeypointPosition = cfg->initialKeypointPosition;
158
159 controller.initPID(cfg->keypointKp,
160 cfg->keypointKi,
161 cfg->keypointKd,
162 cfg->maxControlValue,
163 cfg->maxDerivation);
164
165 // controller.s.numPoints = cfg->numKeypoints;
166 // controller.s.desiredKeypointPosition = cfg->initialKeypointPosition;
167
168
169 rt2mpInfo rt2mp;
170 for (int i = 0; i < cfg->numKeypoints * 3; i++)
171 {
172 mplib::core::DVec state;
173 state.push_back(cfg->initialKeypointPosition[i]);
174 state.push_back(0.0);
175 rt2mp.currentState.push_back(state);
176 }
177 rt2mp.deltaT = 0.0;
178 rt2mpBuffer.reinitAllBuffers(rt2mp);
179 }
180
181 std::string
182 KeypointMPController::getClassName(const Ice::Current&) const
183 {
184 return "KeypointMPController";
185 }
186
187 std::string
189 {
190 return kinematicChainName;
191 }
192
193 void
194 KeypointMPController::rtRun(const IceUtil::Time& /*sensorValuesTimestamp*/,
195 const IceUtil::Time& timeSinceLastIteration)
196 {
198
199 bool valid = controller.updateControlStatus(rtGetControlStruct(),
200 timeSinceLastIteration,
201 torqueSensors,
202 velocitySensors,
203 positionSensors);
204
205 /// for mp controllers you can commit the status buffer now
206 {
207 for (size_t i = 0; i < (unsigned)controller.s.numPoints * 3; i++)
208 {
209 mplib::core::DVec state;
210 state.push_back(controller.s.currentKeypointPosition[i]);
211 state.push_back(0.0);
212 rt2mpBuffer.getWriteBuffer().currentState[i] = state;
213 }
214 rt2mpBuffer.getWriteBuffer().deltaT = controller.s.deltaT;
215 rt2mpBuffer.commitWrite();
216
217 controlStatusBuffer.getWriteBuffer().currentPose = controller.s.currentPose;
218 controlStatusBuffer.getWriteBuffer().currentTwist = controller.s.currentTwist * 1000.0f;
219 controlStatusBuffer.getWriteBuffer().deltaT = controller.s.deltaT;
220 controlStatusBuffer.getWriteBuffer().currentKeypointPosition =
221 controller.s.currentKeypointPosition;
222 controlStatusBuffer.getWriteBuffer().desiredKeypointPosition =
223 controller.s.desiredKeypointPosition;
224 controlStatusBuffer.commitWrite();
225 }
226
227 if (rtFirstRun.load())
228 {
229 rtFirstRun.store(false);
230 rtReady.store(false);
231
232 ftsensor.reset();
233 controller.firstRun();
234 // ARMARX_IMPORTANT << "admittance control first run with\n" << VAROUT(controller.s.desiredTCPPose);
235 }
236 else
237 {
238 ftsensor.compensateTCPGravity(ftSensorBuffer.getReadBuffer());
239 if (!rtReady.load())
240 {
241 if (ftsensor.calibrate(controller.s.deltaT))
242 {
243 rtReady.store(true);
244 }
245 }
246 else
247 {
248 if (valid)
249 {
250 controller.s.currentForceTorque =
251 ftsensor.getFilteredForceTorque(ftSensorBuffer.getReadBuffer());
252 }
253 }
254 }
255
256 const auto& desiredJointTorques = controller.run(rtReady.load());
257 ARMARX_CHECK_EQUAL(int(targets.size()), int(desiredJointTorques.size()));
258
259 /// write torque target to joint device
260 for (size_t i = 0; i < targets.size(); ++i)
261 {
262 targets.at(i)->torque = desiredJointTorques(i);
263 if (!targets.at(i)->isValid())
264 {
265 targets.at(i)->torque = 0;
266 }
267 }
268
269 /// for debug output
270 {
271 controlStatusBuffer.getWriteBuffer().kpImpedance = controller.s.kpImpedance;
272 controlStatusBuffer.getWriteBuffer().kdImpedance = controller.s.kdImpedance;
273 controlStatusBuffer.getWriteBuffer().forceImpedance = controller.s.forceImpedance;
274 controlStatusBuffer.getWriteBuffer().currentForceTorque =
275 controller.s.currentForceTorque;
276
277 controlStatusBuffer.getWriteBuffer().virtualPose = controller.s.virtualPose;
278 controlStatusBuffer.getWriteBuffer().desiredTCPPose = controller.s.desiredTCPPose;
279 controlStatusBuffer.getWriteBuffer().virtualVel = controller.s.virtualVel;
280 controlStatusBuffer.getWriteBuffer().virtualAcc = controller.s.virtualAcc;
281 controlStatusBuffer.getWriteBuffer().currentKeypointPosition =
282 controller.s.currentKeypointPosition;
283 controlStatusBuffer.getWriteBuffer().desiredKeypointPosition =
284 controller.s.desiredKeypointPosition;
285 controlStatusBuffer.getWriteBuffer().filteredKeypointPosition =
286 controller.s.filteredKeypointPosition;
287 controlStatusBuffer.getWriteBuffer().pointTrackingForce =
288 controller.s.pointTrackingForce;
289 controlStatusBuffer.commitWrite();
290 }
291 }
292
293 void
294 KeypointMPController::toggleMP(const bool enableMP, const Ice::Current&)
295 {
296 mpEnabled.store(enableMP);
297 ARMARX_IMPORTANT << "Toggle MP: " << enableMP;
298 }
299
300 bool
302 {
303 return mpEnabled.load();
304 }
305
306 void
307 KeypointMPController::runMP()
308 {
309 if (!rtReady.load() && !mpEnabled.load())
310 {
311 // do something
312 usleep(1000);
313 }
314 else
315 {
316 mplib::core::DVec2d currentState = rt2mpBuffer.getUpToDateReadBuffer().currentState;
317 double deltaT = rt2mpBuffer.getUpToDateReadBuffer().deltaT;
318
319 if (canVal > 1e-8 && mpRunning.load())
320 {
321 double phaseStop = 0;
322 double tau = 1.0;
323
324 canVal -= tau * deltaT * 1 / ((1 + phaseStop) * timeDuration);
325 currentState = pointVMP->calculateDesiredState(canVal, currentState);
326
327 Eigen::VectorXf desiredPosition;
328 desiredPosition.setZero(currentState.size());
329 for (size_t i = 0; i < currentState.size(); i++)
330 {
331 desiredPosition[i] = currentState[i][0];
332 }
333 getWriterControlStruct().desiredKeypointPosition = desiredPosition;
335 }
336 else
337 {
338 // normally set velocity to zero. for keypoint velocity?
339 usleep(1000);
340 }
341 }
342 }
343
344 void
345 KeypointMPController::reconfigureController(const std::string&, const Ice::Current&)
346 {
347 }
348
349 void
351 const std::string& name,
352 const Eigen::Matrix4f& pose)
353 {
354 Eigen::Vector6f vec;
355 vec.head<3>() = pose.block<3, 1>(0, 3);
356 vec.tail<3>() = VirtualRobot::MathTools::eigen4f2rpy(pose);
357 publishVec6f(datafields, name, vec);
358 }
359
360 void
362 const std::string& name,
363 const Eigen::Vector6f& vec)
364 {
365 datafields[name + "_x"] = new Variant(vec(0));
366 datafields[name + "_y"] = new Variant(vec(1));
367 datafields[name + "_z"] = new Variant(vec(2));
368 datafields[name + "_rx"] = new Variant(vec(3));
369 datafields[name + "_ry"] = new Variant(vec(4));
370 datafields[name + "_rz"] = new Variant(vec(5));
371 }
372
373 void
375 const std::string& name,
376 const Eigen::Vector6f& vec)
377 {
378 for (int i = 0; i < vec.size(); i++)
379 {
380 datafields[name + "_" + std::to_string(i)] = new Variant(vec(i));
381 }
382 }
383
384 void
387 const DebugObserverInterfacePrx& debugObs)
388 {
389 StringVariantBaseMap datafields;
390 auto values = debugRTBuffer.getUpToDateReadBuffer().desired_torques;
391 for (auto& pair : values)
392 {
393 datafields[pair.first] = new Variant(pair.second);
394 }
395
396 // publishPose(datafields, "virtual_pose", controlStatusBuffer.getUpToDateReadBuffer().virtualPose);
397 // publishPose(datafields, "desired_pose", controlStatusBuffer.getUpToDateReadBuffer().desiredTCPPose);
398 // publishVec6f(datafields, "virtual_vel", controlStatusBuffer.getUpToDateReadBuffer().virtualVel);
399 // publishVec6f(datafields, "virtual_acc", controlStatusBuffer.getUpToDateReadBuffer().virtualAcc);
400 // publishVec6f(datafields, "kp_Impedance", controlStatusBuffer.getUpToDateReadBuffer().kpImpedance);
401 // publishVec6f(datafields, "kd_Impedance", controlStatusBuffer.getUpToDateReadBuffer().kdImpedance);
402 // publishVec6f(datafields, "force_Impedance", controlStatusBuffer.getUpToDateReadBuffer().forceImpedance);
403 // publishVec6f(datafields, "current_ForceTorque", controlStatusBuffer.getUpToDateReadBuffer().currentForceTorque);
404 // publishVecXf(datafields, "current_KeypointPosition", controlStatusBuffer.getUpToDateReadBuffer().currentKeypointPosition);
405 // publishVecXf(datafields, "desired_KeypointPosition", controlStatusBuffer.getUpToDateReadBuffer().desiredKeypointPosition);
406
407 // Eigen::Matrix4f virtualPose = controlStatusBuffer.getUpToDateReadBuffer().virtualPose;
408 // Eigen::Vector3f rpy = VirtualRobot::MathTools::eigen4f2rpy(virtualPose);
409 // datafields["virtualPose_x"] = new Variant(virtualPose(0, 3));
410 // datafields["virtualPose_y"] = new Variant(virtualPose(1, 3));
411 // datafields["virtualPose_z"] = new Variant(virtualPose(2, 3));
412 // datafields["virtualPose_rx"] = new Variant(rpy(0));
413 // datafields["virtualPose_ry"] = new Variant(rpy(1));
414 // datafields["virtualPose_rz"] = new Variant(rpy(2));
415
416 // Eigen::Matrix4f desiredPose = controlStatusBuffer.getUpToDateReadBuffer().desiredTCPPose;
417 // Eigen::Vector3f rpyDesired = VirtualRobot::MathTools::eigen4f2rpy(desiredPose);
418 // datafields["desiredPose_x"] = new Variant(desiredPose(0, 3));
419 // datafields["desiredPose_y"] = new Variant(desiredPose(1, 3));
420 // datafields["desiredPose_z"] = new Variant(desiredPose(2, 3));
421 // datafields["desiredPose_rx"] = new Variant(rpyDesired(0));
422 // datafields["desiredPose_ry"] = new Variant(rpyDesired(1));
423 // datafields["desiredPose_rz"] = new Variant(rpyDesired(2));
424
425 // datafields["virtualVel_x"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().virtualVel(0));
426 // datafields["virtualVel_y"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().virtualVel(1));
427 // datafields["virtualVel_z"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().virtualVel(2));
428 // datafields["virtualVel_rx"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().virtualVel(3));
429 // datafields["virtualVel_ry"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().virtualVel(4));
430 // datafields["virtualVel_rz"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().virtualVel(5));
431
432 // datafields["virtualAcc_x"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().virtualAcc(0));
433 // datafields["virtualAcc_y"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().virtualAcc(1));
434 // datafields["virtualAcc_z"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().virtualAcc(2));
435 // datafields["virtualAcc_rx"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().virtualAcc(3));
436 // datafields["virtualAcc_ry"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().virtualAcc(4));
437 // datafields["virtualAcc_rz"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().virtualAcc(5));
438
439 // datafields["kpImpedance_x"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().kpImpedance(0));
440 // datafields["kpImpedance_y"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().kpImpedance(1));
441 // datafields["kpImpedance_z"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().kpImpedance(2));
442 // datafields["kpImpedance_rx"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().kpImpedance(3));
443 // datafields["kpImpedance_ry"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().kpImpedance(4));
444 // datafields["kpImpedance_rz"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().kpImpedance(5));
445
446 // datafields["kdImpedance_x"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().kdImpedance(0));
447 // datafields["kdImpedance_y"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().kdImpedance(1));
448 // datafields["kdImpedance_z"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().kdImpedance(2));
449 // datafields["kdImpedance_rx"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().kdImpedance(3));
450 // datafields["kdImpedance_ry"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().kdImpedance(4));
451 // datafields["kdImpedance_rz"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().kdImpedance(5));
452
453 // datafields["forceImpedance_x"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().forceImpedance(0));
454 // datafields["forceImpedance_y"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().forceImpedance(1));
455 // datafields["forceImpedance_z"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().forceImpedance(2));
456 // datafields["forceImpedance_rx"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().forceImpedance(3));
457 // datafields["forceImpedance_ry"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().forceImpedance(4));
458 // datafields["forceImpedance_rz"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().forceImpedance(5));
459
460 // datafields["currentForceTorque_x"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().currentForceTorque(0));
461 // datafields["currentForceTorque_y"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().currentForceTorque(1));
462 // datafields["currentForceTorque_z"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().currentForceTorque(2));
463 // datafields["currentForceTorque_rx"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().currentForceTorque(3));
464 // datafields["currentForceTorque_ry"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().currentForceTorque(4));
465 // datafields["currentForceTorque_rz"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().currentForceTorque(5));
466
467
468 datafields["currentKeypointPosition_x"] =
469 new Variant(controlStatusBuffer.getUpToDateReadBuffer().currentKeypointPosition(0));
470 datafields["currentKeypointPosition_y"] =
471 new Variant(controlStatusBuffer.getUpToDateReadBuffer().currentKeypointPosition(1));
472 datafields["currentKeypointPosition_z"] =
473 new Variant(controlStatusBuffer.getUpToDateReadBuffer().currentKeypointPosition(2));
474 // datafields["currentKeypointPosition_rx"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().currentKeypointPosition(3));
475 // datafields["currentKeypointPosition_ry"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().currentKeypointPosition(4));
476 // datafields["currentKeypointPosition_rz"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().currentKeypointPosition(5));
477
478 datafields["desiredKeypointPosition_x"] =
479 new Variant(controlStatusBuffer.getUpToDateReadBuffer().desiredKeypointPosition(0));
480 datafields["desiredKeypointPosition_y"] =
481 new Variant(controlStatusBuffer.getUpToDateReadBuffer().desiredKeypointPosition(1));
482 datafields["desiredKeypointPosition_z"] =
483 new Variant(controlStatusBuffer.getUpToDateReadBuffer().desiredKeypointPosition(2));
484 // datafields["desiredKeypointPosition_rx"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().desiredKeypointPosition(3));
485 // datafields["desiredKeypointPosition_ry"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().desiredKeypointPosition(4));
486 // datafields["desiredKeypointPosition_rz"] = new Variant(controlStatusBuffer.getUpToDateReadBuffer().desiredKeypointPosition(5));
487
488 datafields["filteredKeypointPosition_x"] =
489 new Variant(controlStatusBuffer.getUpToDateReadBuffer().filteredKeypointPosition(0));
490 datafields["filteredKeypointPosition_y"] =
491 new Variant(controlStatusBuffer.getUpToDateReadBuffer().filteredKeypointPosition(1));
492 datafields["filteredKeypointPosition_z"] =
493 new Variant(controlStatusBuffer.getUpToDateReadBuffer().filteredKeypointPosition(2));
494
495 datafields["track_force_x"] =
496 new Variant(controlStatusBuffer.getUpToDateReadBuffer().pointTrackingForce(0));
497 datafields["track_force_y"] =
498 new Variant(controlStatusBuffer.getUpToDateReadBuffer().pointTrackingForce(1));
499 datafields["track_force_z"] =
500 new Variant(controlStatusBuffer.getUpToDateReadBuffer().pointTrackingForce(2));
501 datafields["track_force_rx"] =
502 new Variant(controlStatusBuffer.getUpToDateReadBuffer().pointTrackingForce(3));
503 datafields["track_force_ry"] =
504 new Variant(controlStatusBuffer.getUpToDateReadBuffer().pointTrackingForce(4));
505 datafields["track_force_rz"] =
506 new Variant(controlStatusBuffer.getUpToDateReadBuffer().pointTrackingForce(5));
507
508 debugObs->setDebugChannel("KeypointMPController", datafields);
509 }
510
511 void
512 KeypointMPController::setTCPPose(const Eigen::Matrix4f& pose, const Ice::Current&)
513 {
514 // LockGuardType guard {controlDataMutex};
515 // getWriterControlStruct().desiredTCPPose = pose;
516 // writeControlStruct();
517 }
518
519 //void KeypointMPController::setNullspaceJointAngles(const Eigen::VectorXf& jointAngles, const Ice::Current &)
520 //{
521 // LockGuardType guard {controlDataMutex};
522 // getWriterControlStruct().desiredNullspaceJointAngles = jointAngles;
523 // writeControlStruct();
524 //}
525
526 void
528 const Eigen::VectorXf& value,
529 const Ice::Current&)
530 {
532 if (name == "kpImpedance")
533 {
534 ARMARX_CHECK_EQUAL(value.size(), 6);
535 getWriterControlStruct().kpImpedance = value;
536 }
537 else if (name == "kdImpedance")
538 {
539 ARMARX_CHECK_EQUAL(value.size(), 6);
540 getWriterControlStruct().kdImpedance = value;
541 }
542 else if (name == "kpAdmittance")
543 {
544 ARMARX_CHECK_EQUAL(value.size(), 6);
545 getWriterControlStruct().kpAdmittance = value;
546 }
547 else if (name == "kdAdmittance")
548 {
549 ARMARX_CHECK_EQUAL(value.size(), 6);
550 getWriterControlStruct().kdAdmittance = value;
551 }
552 else if (name == "kmAdmittance")
553 {
554 ARMARX_CHECK_EQUAL(value.size(), 6);
555 getWriterControlStruct().kmAdmittance = value;
556 }
557 else if (name == "kpNullspaceTorque")
558 {
559 ARMARX_CHECK_EQUAL((unsigned)value.size(), targets.size());
560 getWriterControlStruct().kpNullspaceTorque = value;
561 }
562 else if (name == "kdNullspaceTorque")
563 {
564 ARMARX_CHECK_EQUAL((unsigned)value.size(), targets.size());
565 getWriterControlStruct().kdNullspaceTorque = value;
566 }
567 else
568 {
569 ARMARX_ERROR << name << " is not supported by TaskSpaceAdmittanceController";
570 }
572 }
573
574 void
575 KeypointMPController::setForceTorqueBaseline(const Eigen::Vector3f& forceBaseline,
576 const Eigen::Vector3f& torqueBaseline,
577 const Ice::Current&)
578 {
579 ftSensorBuffer.getWriteBuffer().forceBaseline = forceBaseline;
580 ftSensorBuffer.getWriteBuffer().torqueBaseline = torqueBaseline;
581 ftSensorBuffer.commitWrite();
582 }
583
584 void
585 KeypointMPController::setTCPMass(Ice::Float mass, const Ice::Current&)
586 {
587 ftSensorBuffer.getWriteBuffer().enableTCPGravityCompensation = true;
588 ftSensorBuffer.getWriteBuffer().tcpMass = mass;
589 ftSensorBuffer.commitWrite();
590 }
591
592 void
593 KeypointMPController::setTCPCoMInFTFrame(const Eigen::Vector3f& tcpCoMInFTSensorFrame,
594 const Ice::Current&)
595 {
596 ftSensorBuffer.getWriteBuffer().enableTCPGravityCompensation = true;
597 ftSensorBuffer.getWriteBuffer().tcpCoMInFTSensorFrame = tcpCoMInFTSensorFrame;
598 ftSensorBuffer.commitWrite();
599 }
600
601 void
603 {
604 rtReady.store(false);
605 }
606
607 std::string
609 {
610 return "KeypointMP";
611 }
612
613 void
614 KeypointMPController::start(const Ice::DoubleSeq& goal, const Ice::Current&)
615 {
616 pointVMP->prepareExecution(goal, initialState, 1.0);
617 mplib::representation::MPStateVec initState =
618 mplib::core::SystemState::convert2DArrayToStates<mplib::representation::MPState>(
619 initialState);
620 }
621
622 void
623 KeypointMPController::startWithTime(const Ice::DoubleSeq& goal,
624 Ice::Double duration,
625 const Ice::Current&)
626 {
627 timeDuration = duration;
628 pointVMP->prepareExecution(goal, initialState, 1.0);
629 mplib::representation::MPStateVec initState =
630 mplib::core::SystemState::convert2DArrayToStates<mplib::representation::MPState>(
631 initialState);
632 mpRunning.store(true);
633 }
634
635 void
637 {
638 pointVMP->prepareExecution(goal, initialState, 1.0);
639 mplib::representation::MPStateVec initState =
640 mplib::core::SystemState::convert2DArrayToStates<mplib::representation::MPState>(
641 initialState);
642 }
643
644 void
645 KeypointMPController::startAsTrajWithTime(Ice::Double duration, const Ice::Current&)
646 {
647 }
648
649 void
650 KeypointMPController::stop(const Ice::Current&)
651 {
652 mpRunning.store(false);
653 }
654
655 void
656 KeypointMPController::pause(const Ice::Current&)
657 {
658 mpRunning.store(false);
659 }
660
661 void
662 KeypointMPController::resume(const Ice::Current&)
663 {
664 mpRunning.store(true);
665 }
666
667 void
668 KeypointMPController::reset(const Ice::Current&)
669 {
670 if (mpRunning.load())
671 {
672 ARMARX_INFO << "Cannot reset running DMP";
673 }
674 rtFirstRun = true;
675 }
676
677 bool
679 {
680 return !mpRunning.load();
681 }
682
683 void
684 KeypointMPController::learnFromCSV(const Ice::StringSeq& fileList, const Ice::Current&)
685 {
686 std::vector<mplib::core::SampledTrajectory> trajs;
687 for (auto& file : fileList)
688 {
689 mplib::core::SampledTrajectory traj;
690 traj.readFromCSVFile(file);
691 trajs.push_back(traj);
692 }
693 pointVMP->learnFromTrajectories(trajs);
694
695 ARMARX_CHECK_EQUAL(trajs[0].dim(), (unsigned)numPoints * 3);
696 initialState.clear();
697 goal.clear();
698
699 for (size_t i = 0; i < trajs[0].dim(); i++)
700 {
701 mplib::core::DVec state;
702 // state.push_back(trajs[0].begin()->getPosition(i));
703 // state.push_back(trajs[0].begin()->getDeriv(i, 1));
704 state.push_back(initialStateEigen[i]);
705 state.push_back(0.0);
706 initialState.push_back(state);
707 goal.push_back(trajs[0].rbegin()->getPosition(i));
708 }
709 }
710
711 void
712 KeypointMPController::setGoal(const Ice::DoubleSeq&, const Ice::Current&)
713 {
714 }
715
716 void
718 const Ice::DoubleSeq&,
719 const Ice::Current&)
720 {
721 }
722
723 void
724 KeypointMPController::setViaPoint(Ice::Double, const Ice::DoubleSeq&, const Ice::Current&)
725 {
726 }
727
728 void
730 {
731 }
732
733 std::string
735 {
736 // std::stringstream ss;
737 // boost::archive::text_oarchive oa{ss};
738 // oa << pointVMP.get();
739 // return ss.str();
740 return "notImplemented";
741 }
742
743 Ice::DoubleSeq
744 KeypointMPController::deserialize(const std::string& mpAsString, const Ice::Current&)
745 {
746 // std::stringstream ss;
747 // ss.str(mpAsString);
748 // boost::archive::text_iarchive ia{ss};
749
750 // VMPPtr mpPointer;
751 // ia >> mpPointer;
752 // pointVMP.reset(mpPointer);
753 // return pointVMP->defaultGoal;
754 std::vector<double> dummy;
755 dummy.push_back(0.0);
756 return dummy;
757 }
758
759 Ice::Double
761 {
762 return canVal;
763 }
764
765 void
766 KeypointMPController::toggleGravityCompensation(const bool toggle, const Ice::Current&)
767 {
768 ftSensorBuffer.getWriteBuffer().enableTCPGravityCompensation = toggle;
769 ftSensorBuffer.commitWrite();
770 rtReady.store(false); /// you also need to re-calibrate ft sensor
771 }
772
773 void
775 {
776 VirtualRobot::RobotNodeSetPtr rns = rtGetRobot()->getRobotNodeSet(kinematicChainName);
777 Eigen::Matrix4f currentPose = rns->getTCP()->getPoseInRootFrame();
778 ARMARX_IMPORTANT << "rt preactivate controller with target pose\n\n" << currentPose;
779 controller.s.currentPose = currentPose;
780 controller.s.desiredTCPPose = currentPose;
781 controller.s.previousTargetPose = currentPose;
782 controller.s.virtualPose = currentPose;
783 controller.desiredPose = currentPose;
784 controller.s.virtualVel.setZero();
785 controller.s.virtualAcc.setZero();
786 Eigen::VectorXf fixedTranslation;
787 fixedTranslation.setZero(controller.s.currentKeypointPosition.size());
789 << VAROUT(controller.s.currentKeypointPosition);
790 if (controller.s.isRigid)
791 {
792 for (int i = 0; i < numPoints; i++)
793 {
794 fixedTranslation.segment(3 * i, 3) =
795 controller.s.currentKeypointPosition.segment(3 * i, 3) -
796 currentPose.block<3, 1>(0, 3);
797 }
798 ARMARX_IMPORTANT << VAROUT(fixedTranslation);
799 }
800 controller.s.fixedTranslation = fixedTranslation;
801 controller.pid->reset();
802 getWriterControlStruct().fixedTranslation = controller.s.fixedTranslation;
803 getWriterControlStruct().desiredTCPPose = currentPose;
805 }
806
807 void
809 {
810 runTask("KeypointMPController",
811 [&]
812 {
813 CycleUtil c(1);
814 getObjectScheduler()->waitForObjectStateMinimum(eManagedIceObjectStarted);
815 ARMARX_IMPORTANT << "Try to run mp";
816 while (getState() == eManagedIceObjectStarted)
817 {
818 if (isControllerActive())
819 {
820 runMP();
821 }
822 c.waitForCycleDuration();
823 }
824 });
825 }
826
827 void
828 KeypointMPController::setKeypoints(const Eigen::VectorXf& keypointPosition, const Ice::Current&)
829 {
831 ARMARX_CHECK_EQUAL(getWriterControlStruct().currentKeypointPosition.size(),
832 keypointPosition.size());
833 getWriterControlStruct().currentKeypointPosition = keypointPosition;
835 }
836
837 void
839 const float keypoint_stiffness,
840 const bool is_rigid,
841 const Eigen::VectorXf& ctrl_mask,
842 const Eigen::VectorXf& init_keypoints_position,
843 const Ice::Current&)
844 {
845 numPoints = n_points;
846 getWriterControlStruct().numPoints = n_points;
847 getWriterControlStruct().keypointKp = keypoint_stiffness;
848 getWriterControlStruct().isRigid = is_rigid;
849 getWriterControlStruct().pointCtrlMask = ctrl_mask;
850 getWriterControlStruct().currentKeypointPosition = init_keypoints_position;
852 }
853} // namespace armarx::control::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...
void reinitTripleBuffer(const law::TaskspaceKeypointsAdmittanceController::Config &initial)
The SensorValueBase class.
const T * asA() const
const T & getUpToDateReadBuffer() const
The Variant class is described here: Variants.
Definition Variant.h:224
void onPublish(const SensorAndControl &, const DebugDrawerInterfacePrx &, const DebugObserverInterfacePrx &) override
void setGoal(const Ice::DoubleSeq &, const Ice::Current &) override
void reconfigureController(const std::string &, const Ice::Current &) override
void start(const Ice::DoubleSeq &, const Ice::Current &) override
void learnFromCSV(const Ice::StringSeq &, const Ice::Current &) override
KeypointMPController(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &)
void resetKeypoints(const int n_points, const float keypoint_stiffness, const bool is_rigid, const Eigen::VectorXf &ctrl_mask, const Eigen::VectorXf &init_keypoints_position, const Ice::Current &) override
void setKeypoints(const Eigen::VectorXf &, const Ice::Current &) override
void toggleMP(const bool enableMP, const Ice::Current &) override
void setStartAndGoal(const Ice::DoubleSeq &, const Ice::DoubleSeq &, const Ice::Current &) override
void setForceTorqueBaseline(const Eigen::Vector3f &, const Eigen::Vector3f &, const Ice::Current &) override
Ice::DoubleSeq deserialize(const std::string &mpAsString, const Ice::Current &) override
void rtRun(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration) override
TODO make protected and use attorneys.
void setTCPCoMInFTFrame(const Eigen::Vector3f &, const Ice::Current &) override
void publishPose(StringVariantBaseMap &datafields, const std::string &name, const Eigen::Matrix4f &pose)
void setViaPoint(Ice::Double, const Ice::DoubleSeq &, const Ice::Current &) override
void setTCPPose(const Eigen::Matrix4f &, const Ice::Current &) override
void startWithTime(const Ice::DoubleSeq &, Ice::Double, const Ice::Current &) override
void publishVec6f(StringVariantBaseMap &datafields, const std::string &name, const Eigen::Vector6f &vec)
void setControlParameters(const std::string &, const Eigen::VectorXf &, const Ice::Current &) override
set control parameter
void publishVecXf(StringVariantBaseMap &datafields, const std::string &name, const Eigen::Vector6f &vec)
void rtPreActivateController() override
This function is called before the controller is activated.
void toggleGravityCompensation(const bool toggle, const Ice::Current &) override
ft sensor
#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_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:179
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:188
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:194
#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< KeypointMPController > registrationControllerKeypointMPController("KeypointMPController")
::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