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