CollisionAvoidanceImpedanceController.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 ...
17 * @author Jianfeng Gao ( jianfeng dot gao at kit dot edu )
18 * @date 2021
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
24
25#include <VirtualRobot/MathTools.h>
26#include <VirtualRobot/RobotNodeSet.h>
27
28#include <simox/control/geodesics/util.h>
29#include <simox/control/robot/NodeInterface.h>
30
32#include <ArmarXCore/core/PackagePath.h> // for GUI
36
41
45
47{
48 NJointControllerRegistration<NJointTaskspaceCollisionAvoidanceImpedanceController>
50 "NJointTaskspaceCollisionAvoidanceImpedanceController");
51
55 const NJointControllerConfigPtr& config,
56 const VirtualRobot::RobotPtr& robot) :
58 {
59 ConfigPtrT cfg = ConfigPtrT::dynamicCast(config);
61 userCfgWithColl = CollisionCtrlCfg::FromAron(cfg->config);
62
63 std::map<std::string, std::vector<size_t>> velCtrlIndices;
64
65 coll = std::make_shared<core::CollisionAvoidanceBase>(
66 rtGetRobot(), userCfgWithColl.coll, velCtrlIndices);
67 collReady.store(true);
68 ARMARX_INFO << "-- " << getClassName() << " initialized --";
69 }
70
71 std::string
73 {
74 return "NJointTaskspaceCollisionAvoidanceImpedanceController";
75 }
76
77 void
79 {
80 double time_measure = IceUtil::Time::now().toMicroSecondsDouble();
81 // limbRTUpdateStatus(arm, deltaT);
82 double time_update_status = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
83
84 arm->controller.run(arm->rtConfig, arm->rtStatus);
85 double time_run_rt = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
86
87 if (collReady.load())
88 {
90 coll->rtLimbControllerRun(arm->kinematicChainName,
91 arm->rtStatus.jointPosition,
92 arm->rtStatus.qvelFiltered,
93 arm->rtConfig.torqueLimit,
94 arm->rtStatus.desiredJointTorque,
95 deltaT);
96 }
97 double time_coll_run = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
98
99 if (collReady.load())
100 {
101 limbRTSetTarget(arm,
102 coll->collLimb.at(arm->kinematicChainName).rts.desiredJointTorques);
103 }
104 else
105 {
106 limbRTSetTarget(arm, arm->rtStatus.desiredJointTorque);
107 }
108 double time_set_target = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
109
110 time_measure = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
111
112 if (time_measure > 200)
113 {
114 ARMARX_RT_LOGF_WARN("---- rt too slow: "
115 "time_update_status: %.2f\n"
116 "run_rt_limb: %.2f\n"
117 "run_coll_rt_limb: %.2f\n"
118 "set_target_limb: %.2f\n"
119 "time all: %.2f\n",
120 time_update_status, // 0-1 us
121 time_run_rt - time_update_status, //
122 time_coll_run - time_run_rt, //
123 time_set_target - time_coll_run, //
124 time_measure)
125 .deactivateSpam(1.0f); // 0-1 us
126 }
127 }
128
129 void
131 const IceUtil::Time& sensorValuesTimestamp,
132 const IceUtil::Time& timeSinceLastIteration)
133 {
134 double deltaT = timeSinceLastIteration.toSecondsDouble();
135
136 if (collReady.load())
137 {
139 coll->updateRtConfigFromUser();
140 coll->rtCollisionChecking();
141 }
142 for (auto& pair : limb)
143 {
144 limbRTUpdateStatus(pair.second, deltaT);
145 }
146
147 rtRunCoordinator(deltaT);
148
149 for (auto& pair : limb)
150 {
151 limbRT(pair.second, deltaT);
152 }
153 if (hands)
154 {
155 hands->updateRTStatus(deltaT);
156 }
157 }
158
159 void
161 const ::armarx::aron::data::dto::DictPtr& dto,
162 const Ice::Current& iceCurrent)
163 {
165 auto cfg = common::control_law::arondto::CollisionAvoidanceConfigDict::FromAron(dto);
166 coll->setUserCfg(cfg);
167 }
168
171 const Ice::Current& iceCurrent)
172 {
173 if (not collReady.load())
174 return nullptr;
175
177 return coll->userCfg.toAronDTO();
178 }
179
180 void
182 const ::armarx::aron::data::dto::DictPtr& dto,
183 const Ice::Current& iceCurrent)
184 {
186 userCfgWithColl = CollisionCtrlCfg::FromAron(dto);
188 coll->setUserCfg(userCfgWithColl.coll);
189 }
190
193 {
195 userCfgWithColl.limbs = userConfig.limbs;
196 userCfgWithColl.hands = userConfig.hands;
197 return userCfgWithColl.toAronDTO();
198 }
199
200 void
203 const DebugObserverInterfacePrx& debugObs)
204 {
205 // double limbTimeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
206
207 StringVariantBaseMap datafields;
208 auto rtStatus = arm.bufferRTtoPublish.getUpToDateReadBuffer();
209
210 datafields["trackingError"] = new Variant(rtStatus.trackingError);
211 common::debugEigenVec(datafields, "desiredJointTorques", rtStatus.desiredJointTorques);
212 common::debugEigenVec(datafields, "selfCollisionTorque", rtStatus.selfCollisionJointTorque);
213 common::debugEigenVec(datafields, "jointLimitTorque", rtStatus.jointLimitJointTorque);
214
216 datafields, "projectedImpedanceTorque", rtStatus.projImpedanceJointTorque);
217 // common::debugEigenVec(datafields, "projectedJointLimitTorque", rtStatus.projJointLimTorque);
218 // common::debugEigenVec(datafields, "projectedForceImpedance", rtStatus.projForceImpedance);
219 // common::debugEigenVec(
220 // datafields, "projectedSelfCollisionTorque", rtStatus.projSelfCollTorque);
221
222 Eigen::VectorXf selfCollNullspace = rtStatus.selfCollNullSpace.diagonal();
223 Eigen::VectorXf jointLimNullspace = rtStatus.jointLimNullSpace.diagonal();
224 common::debugEigenVec(datafields, "selfCollNullspaceDiagonal", selfCollNullspace);
225 common::debugEigenVec(datafields, "jointLimNullspaceDiagonal", jointLimNullspace);
226
227 // if (rtData.enableJointLimitAvoidance)
228 // {
229 // for (size_t i = 0; i < rtStatus.jointLimitData.size(); ++i)
230 // {
231 // if (not rtStatus.jointLimitData[i].isLimitless)
232 // {
233 // datafields["n_des(q)_" + std::to_string(i) + "_" +
234 // rtStatus.jointLimitData[i].jointName] =
235 // new Variant(rtStatus.jointLimitData[i].desiredNSjointLim);
236 // datafields["q_damping" + std::to_string(i) + "_" +
237 // rtStatus.jointLimitData[i].jointName] =
238 // new Variant(rtStatus.jointLimitData[i].totalDamping);
239 // datafields["q_repTorque" + std::to_string(i) + "_" +
240 // rtStatus.jointLimitData[i].jointName] =
241 // new Variant(rtStatus.jointLimitData[i].repulsiveTorque);
242 // }
243 // }
244 // }
245
246 // datafields["activeCollPairsNum"] = new Variant(rtStatus.activeCollPairsNum);
247 // datafields["collisionPairsNum"] = new Variant(rtStatus.collisionPairsNum);
248 // datafields["jointLimitNullspaceTime"] = new Variant(rtStatus.jointLimitNullspaceTime);
249 // datafields["jointLimitTorqueTime"] = new Variant(rtStatus.jointLimitTorqueTime);
250 // datafields["collisionTorqueTime"] = new Variant(rtStatus.collisionTorqueTime);
251 // datafields["collNullspaceTime"] = new Variant(rtStatus.collNullspaceTime);
252 // datafields["collisionPairTime"] = new Variant(rtStatus.collisionPairTime);
253 // datafields["impForceRatio"] = new Variant(rtStatus.impForceRatio);
254 // datafields["impTorqueRatio"] = new Variant(rtStatus.impTorqueRatio);
255
256 // double timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
257 // viz::Layer layer = arviz.layer(getName() + "_" + arm->nodeSetName);
258 // for (int i = 0; i < rtStatus.activeCollPairsNum; ++i)
259 // {
260 // // visualize impedance force
261
262 // // layer.add(viz::Arrow("projImpForce_" + std::to_string(i))
263 // // .fromTo(rtStatus.collDataVec[i].point * 1000.0,
264 // // rtStatus.collDataVec[i].point * 1000.0 +
265 // // rtStatus.collDataVec[i].projectedImpedanceForce *
266 // // rtStatus.collDataVec[i].direction * 5.0)
267 // // .color(simox::Color::purple()));
268
269 // // layer.add(viz::Arrow("impForce_" + std::to_string(i))
270 // // .fromTo(rtStatus.collDataVec[i].point * 1000.0,
271 // // rtStatus.collDataVec[i].point * 1000.0 +
272 // // rtStatus.forceImpedance.head<3>().dot(
273 // // rtStatus.collDataVec[i].direction) *
274 // // rtStatus.collDataVec[i].direction * 5.0)
275 // // .color(simox::Color::yellow())); // project forceImp in dir of collision
276 // layer.add(viz::Arrow("force_" + std::to_string(i))
277 // .fromTo(rtStatus.collDataVec[i].point * 1000.0,
278 // rtStatus.collDataVec[i].point * 1000.0 +
279 // rtStatus.collDataVec[i].direction * 50.0 *
280 // rtStatus.collDataVec[i].repulsiveForce)
281 // .color(simox::Color::blue()));
282
283 // //
284
285 // // //size_t index = rtStatus.distanceIndexPairs[i].second;
286 // // datafields[std::to_string(i) + "_minDistance"] =
287 // // new Variant(rtStatus.collDataVec[i].minDistance);
288 // // datafields[std::to_string(i) + "_repForce"] =
289 // // new Variant(rtStatus.collDataVec[i].repulsiveForce);
290 // // datafields[std::to_string(i) + "_dampingForce"] =
291 // // new Variant(-1.0f * rtStatus.collDataVec[i].damping *
292 // // rtStatus.collDataVec[i].distanceVelocity);
293 // // datafields[std::to_string(i) + "_n_des(d)"] =
294 // // new Variant(rtStatus.collDataVec[i].desiredNSColl);
295 // // common::debugEigenVec(
296 // // datafields, std::to_string(i) + "_point", rtStatus.collDataVec[i].point);
297 // // common::debugEigenVec(
298 // // datafields, std::to_string(i) + "_dir", rtStatus.collDataVec[i].direction);
299 // //
300 // }
301
302
303 // /// prepare test case config
304 // const float tolerance = 1e-9f;
305 // if (rtData.testConfig == 1)
306 // {
307 // if (rtStatus.evalData[0].nodeName == "ArmL8_Wri2")
308 // {
309 // // set distance
310 // datafields["ArmL8_Wri2_" + rtStatus.evalData[0].otherName + "_dist"] =
311 // new Variant(rtStatus.evalData[0].minDistance);
312 // // set f_rep, damping, desired NS space
313
314
315 // datafields["ArmL8_Wri2_" + rtStatus.evalData[0].otherName + "_repF"] =
316 // new Variant(rtStatus.evalData[0].repulsiveForce);
317 // datafields["ArmL8_Wri2_" + rtStatus.evalData[0].otherName + "_projMass"] =
318 // new Variant(rtStatus.evalData[0].projectedMass);
319 // datafields["ArmL8_Wri2_" + rtStatus.evalData[0].otherName + "_locStiffness"] =
320 // new Variant(rtStatus.evalData[0].localStiffness);
321 // datafields["ArmL8_Wri2_" + rtStatus.evalData[0].otherName + "_dampFactor"] =
322 // new Variant(rtStatus.evalData[0].damping);
323 // datafields["ArmL8_Wri2_" + rtStatus.evalData[0].otherName + "_distVel"] =
324 // new Variant(rtStatus.evalData[0].distanceVelocity);
325 // if (fabs(rtStatus.evalData[0].damping + 1.0f) < tolerance)
326 // {
327 // datafields["ArmL8_Wri2_" + rtStatus.evalData[0].otherName + "_dampForce"] =
328 // new Variant(0.0);
329 // }
330 // else
331 // {
332 // datafields["ArmL8_Wri2_" + rtStatus.evalData[0].otherName + "_dampForce"] =
333 // new Variant(-1.0 * rtStatus.evalData[0].damping *
334 // rtStatus.evalData[0].distanceVelocity);
335 // }
336
337 // datafields["ArmL8_Wri2_" + rtStatus.evalData[0].otherName + "_n_des(d)"] =
338 // new Variant(rtStatus.evalData[0].desiredNSColl);
339 // }
340 // if (rtStatus.evalData[1].nodeName == "ArmL8_Wri2")
341 // {
342 // // set distance
343 // datafields["ArmL8_Wri2_" + rtStatus.evalData[1].otherName + "_dist"] =
344 // new Variant(rtStatus.evalData[1].minDistance);
345 // // set f_rep, damping, desired NS space
346
347 // datafields["ArmL8_Wri2_" + rtStatus.evalData[1].otherName + "_repF"] =
348 // new Variant(rtStatus.evalData[1].repulsiveForce);
349 // datafields["ArmL8_Wri2_" + rtStatus.evalData[1].otherName + "_projMass"] =
350 // new Variant(rtStatus.evalData[1].projectedMass);
351 // datafields["ArmL8_Wri2_" + rtStatus.evalData[1].otherName + "_locStiffness"] =
352 // new Variant(rtStatus.evalData[1].localStiffness);
353 // datafields["ArmL8_Wri2_" + rtStatus.evalData[1].otherName + "_dampFactor"] =
354 // new Variant(rtStatus.evalData[1].damping);
355 // datafields["ArmL8_Wri2_" + rtStatus.evalData[1].otherName + "_distVel"] =
356 // new Variant(rtStatus.evalData[1].distanceVelocity);
357 // if (fabs(rtStatus.evalData[1].damping + 1.0f) < tolerance)
358 // {
359 // datafields["ArmL8_Wri2_" + rtStatus.evalData[1].otherName + "_dampForce"] =
360 // new Variant(0.0);
361 // }
362 // else
363 // {
364 // datafields["ArmL8_Wri2_" + rtStatus.evalData[1].otherName + "_dampForce"] =
365 // new Variant(-1.0 * rtStatus.evalData[1].damping *
366 // rtStatus.evalData[1].distanceVelocity);
367 // }
368
369 // datafields["ArmL8_Wri2_" + rtStatus.evalData[1].otherName + "_n_des(d)"] =
370 // new Variant(rtStatus.evalData[1].desiredNSColl);
371 // }
372 // if (rtStatus.evalData[2].nodeName == "ArmL7_Wri1")
373 // {
374 // // set distance
375 // datafields["ArmL7_Wri1_" + rtStatus.evalData[2].otherName + "_dist"] =
376 // new Variant(rtStatus.evalData[2].minDistance);
377 // // set f_rep, damping, desired NS space
378
379 // datafields["ArmL7_Wri1_" + rtStatus.evalData[2].otherName + "_repF"] =
380 // new Variant(rtStatus.evalData[2].repulsiveForce);
381
382 // datafields["ArmL7_Wri1_" + rtStatus.evalData[2].otherName + "_projMass"] =
383 // new Variant(rtStatus.evalData[2].projectedMass);
384 // datafields["ArmL7_Wri1_" + rtStatus.evalData[2].otherName + "_locStiffness"] =
385 // new Variant(rtStatus.evalData[2].localStiffness);
386 // datafields["ArmL7_Wri1_" + rtStatus.evalData[2].otherName + "_dampFactor"] =
387 // new Variant(rtStatus.evalData[2].damping);
388 // datafields["ArmL7_Wri1_" + rtStatus.evalData[2].otherName + "_distVel"] =
389 // new Variant(rtStatus.evalData[2].distanceVelocity);
390 // if (fabs(rtStatus.evalData[2].damping + 1.0f) < tolerance)
391 // {
392 // datafields["ArmL7_Wri1_" + rtStatus.evalData[2].otherName + "_dampForce"] =
393 // new Variant(0.0);
394 // }
395 // else
396 // {
397 // datafields["ArmL7_Wri1_" + rtStatus.evalData[2].otherName + "_dampForce"] =
398 // new Variant(-1.0 * rtStatus.evalData[2].damping *
399 // rtStatus.evalData[2].distanceVelocity);
400 // }
401
402
403 // datafields["ArmL7_Wri1_" + rtStatus.evalData[2].otherName + "_n_des(d)"] =
404 // new Variant(rtStatus.evalData[2].desiredNSColl);
405 // }
406 // if (rtStatus.evalData[3].nodeName == "ArmL8_Wri2")
407 // {
408 // // set distance
409 // datafields["ArmL8_Wri2_" + rtStatus.evalData[3].otherName + "_dist"] =
410 // new Variant(rtStatus.evalData[3].minDistance);
411 // // set f_rep, damping, desired NS space
412
413 // datafields["ArmL8_Wri2_" + rtStatus.evalData[3].otherName + "_repF"] =
414 // new Variant(rtStatus.evalData[3].repulsiveForce);
415
416 // datafields["ArmL8_Wri2_" + rtStatus.evalData[3].otherName + "_projMass"] =
417 // new Variant(rtStatus.evalData[3].projectedMass);
418 // datafields["ArmL8_Wri2_" + rtStatus.evalData[3].otherName + "_locStiffness"] =
419 // new Variant(rtStatus.evalData[3].localStiffness);
420 // datafields["ArmL8_Wri2_" + rtStatus.evalData[3].otherName + "_dampFactor"] =
421 // new Variant(rtStatus.evalData[3].damping);
422 // datafields["ArmL8_Wri2_" + rtStatus.evalData[3].otherName + "_distVel"] =
423 // new Variant(rtStatus.evalData[3].distanceVelocity);
424 // if (fabs(rtStatus.evalData[3].damping + 1.0f) < tolerance)
425 // {
426 // datafields["ArmL8_Wri2_" + rtStatus.evalData[3].otherName + "_dampForce"] =
427 // new Variant(0.0);
428 // }
429 // else
430 // {
431 // datafields["ArmL8_Wri2_" + rtStatus.evalData[3].otherName + "_dampForce"] =
432 // new Variant(-1.0 * rtStatus.evalData[3].damping *
433 // rtStatus.evalData[3].distanceVelocity);
434 // }
435
436
437 // datafields["ArmL8_Wri2_" + rtStatus.evalData[3].otherName + "_n_des(d)"] =
438 // new Variant(rtStatus.evalData[3].desiredNSColl);
439 // }
440
441 // if (rtStatus.evalData[4].nodeName == "ArmL8_Wri2")
442 // {
443 // // set distance
444 // datafields["ArmL8_Wri2_" + rtStatus.evalData[4].otherName + "_dist"] =
445 // new Variant(rtStatus.evalData[4].minDistance);
446 // // set f_rep, damping, desired NS space
447
448 // // values have been calculated
449 // datafields["ArmL8_Wri2_" + rtStatus.evalData[4].otherName + "_repF"] =
450 // new Variant(rtStatus.evalData[4].repulsiveForce);
451
452 // datafields["ArmL8_Wri2_" + rtStatus.evalData[4].otherName + "_projMass"] =
453 // new Variant(rtStatus.evalData[4].projectedMass);
454 // datafields["ArmL8_Wri2_" + rtStatus.evalData[4].otherName + "_locStiffness"] =
455 // new Variant(rtStatus.evalData[4].localStiffness);
456 // datafields["ArmL8_Wri2_" + rtStatus.evalData[4].otherName + "_dampFactor"] =
457 // new Variant(rtStatus.evalData[4].damping);
458 // datafields["ArmL8_Wri2_" + rtStatus.evalData[4].otherName + "_distVel"] =
459 // new Variant(rtStatus.evalData[4].distanceVelocity);
460 // if (fabs(rtStatus.evalData[4].damping + 1.0f) < tolerance)
461 // {
462 // datafields["ArmL8_Wri2_" + rtStatus.evalData[4].otherName + "_dampForce"] =
463 // new Variant(0.0);
464 // }
465 // else
466 // {
467 // datafields["ArmL8_Wri2_" + rtStatus.evalData[4].otherName + "_dampForce"] =
468 // new Variant(-1.0 * rtStatus.evalData[4].damping *
469 // rtStatus.evalData[4].distanceVelocity);
470 // }
471
472
473 // datafields["ArmL8_Wri2_" + rtStatus.evalData[4].otherName + "_n_des(d)"] =
474 // new Variant(rtStatus.evalData[4].desiredNSColl);
475 // }
476 // if (rtStatus.evalData[5].nodeName == "ArmL8_Wri2")
477 // {
478 // // set distance
479 // datafields["ArmL8_Wri2_" + rtStatus.evalData[5].otherName + "_dist"] =
480 // new Variant(rtStatus.evalData[5].minDistance);
481
482 // // values have been calculated
483 // datafields["ArmL8_Wri2_" + rtStatus.evalData[5].otherName + "_repF"] =
484 // new Variant(rtStatus.evalData[5].repulsiveForce);
485
486 // datafields["ArmL8_Wri2_" + rtStatus.evalData[5].otherName + "_projMass"] =
487 // new Variant(rtStatus.evalData[5].projectedMass);
488 // datafields["ArmL8_Wri2_" + rtStatus.evalData[5].otherName + "_locStiffness"] =
489 // new Variant(rtStatus.evalData[5].localStiffness);
490 // datafields["ArmL8_Wri2_" + rtStatus.evalData[5].otherName + "_dampFactor"] =
491 // new Variant(rtStatus.evalData[5].damping);
492 // datafields["ArmL8_Wri2_" + rtStatus.evalData[5].otherName + "_distVel"] =
493 // new Variant(rtStatus.evalData[5].distanceVelocity);
494 // if (fabs(rtStatus.evalData[5].damping + 1.0f) < tolerance)
495 // {
496 // datafields["ArmL8_Wri2_" + rtStatus.evalData[5].otherName + "_dampForce"] =
497 // new Variant(0.0);
498 // }
499 // else
500 // {
501 // datafields["ArmL8_Wri2_" + rtStatus.evalData[5].otherName + "_dampForce"] =
502 // new Variant(-1.0 * rtStatus.evalData[5].damping *
503 // rtStatus.evalData[5].distanceVelocity);
504 // }
505
506
507 // datafields["ArmL8_Wri2_" + rtStatus.evalData[5].otherName + "_n_des(d)"] =
508 // new Variant(rtStatus.evalData[5].desiredNSColl);
509 // }
510 // if (rtStatus.evalData[6].nodeName == "ArmL5_Elb1")
511 // {
512 // // set distance
513 // datafields["ArmL5_Elb1_" + rtStatus.evalData[6].otherName + "_dist"] =
514 // new Variant(rtStatus.evalData[6].minDistance);
515
516 // // values have been calculated
517 // datafields["ArmL5_Elb1_" + rtStatus.evalData[6].otherName + "_repF"] =
518 // new Variant(rtStatus.evalData[6].repulsiveForce);
519
520 // datafields["ArmL5_Elb1_" + rtStatus.evalData[6].otherName + "_projMass"] =
521 // new Variant(rtStatus.evalData[6].projectedMass);
522 // datafields["ArmL5_Elb1_" + rtStatus.evalData[6].otherName + "_locStiffness"] =
523 // new Variant(rtStatus.evalData[6].localStiffness);
524 // datafields["ArmL5_Elb1_" + rtStatus.evalData[6].otherName + "_dampFactor"] =
525 // new Variant(rtStatus.evalData[6].damping);
526 // datafields["ArmL5_Elb1_" + rtStatus.evalData[6].otherName + "_distVel"] =
527 // new Variant(rtStatus.evalData[6].distanceVelocity);
528 // if (fabs(rtStatus.evalData[6].damping + 1.0f) < tolerance)
529 // {
530 // datafields["ArmL5_Elb1_" + rtStatus.evalData[6].otherName + "_dampForce"] =
531 // new Variant(0.0);
532 // }
533 // else
534 // {
535 // datafields["ArmL5_Elb1_" + rtStatus.evalData[6].otherName + "_dampForce"] =
536 // new Variant(-1.0 * rtStatus.evalData[6].damping *
537 // rtStatus.evalData[6].distanceVelocity);
538 // }
539
540
541 // datafields["ArmL5_Elb1_" + rtStatus.evalData[6].otherName + "_n_des(d)"] =
542 // new Variant(rtStatus.evalData[6].desiredNSColl);
543 // }
544 // }
545
546 // visualize impedance force
547
548 // layer.add(viz::Arrow("impForce")
549 // .fromTo(rtStatus.currentPose.block<3, 1>(0, 3),
550 // rtStatus.currentPose.block<3, 1>(0, 3) +
551 // rtStatus.forceImpedance.head<3>() * 1000.0)
552 // .color(simox::Color::yellow()));
553 // layer.add(viz::Arrow("projImpForce")
554 // .fromTo(rtStatus.currentPose.block<3, 1>(0, 3),
555 // rtStatus.currentPose.block<3, 1>(0, 3) +
556 // rtStatus.projForceImpedance.head<3>() * 1000.0)
557 // .color(simox::Color::purple()));
558
559 // arviz.commit(layer);
560
561
562 //double selfCollDebugTime = IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
563 //datafields["selfCollDebugTime"] = new Variant(selfCollDebugTime);
564
565 // debug value assignment torso, neck joints
566 // datafields["torsoJointValue_float"] = new Variant(rtStatus.torsoJointValuef);
567 // datafields["neck1JointValue_float"] = new Variant(rtStatus.neck1JointValuef);
568 // datafields["neck2JointValue_float"] = new Variant(rtStatus.neck2JointValuef);
569
570 // datafields["torsoJointValue_double"] = new Variant(rtStatus.torsoJointValued);
571 // datafields["neck1JointValue_double"] = new Variant(rtStatus.neck1JointValued);
572 // datafields["neck2JointValue_double"] = new Variant(rtStatus.neck2JointValued);
573
574 // common::debugEigenVec(
575 // datafields, "set_ActuatedJointValues", rtStatus.setActuatedJointValues.cast<float>());
576 // common::debugEigenVec(
577 // datafields, "get_ActuatedJointValues", rtStatus.getActuatedJointValues.cast<float>());
578
579 // double limbTime = IceUtil::Time::now().toMicroSecondsDouble() - limbTimeMeasure;
580 // datafields["limbOnPublishTime"] = new Variant(limbTime);
581
582 debugObs->setDebugChannel("CollAvoid_ImpCtrl_" + arm.nodeSetName, datafields);
583 }
584
585 void
587 const SensorAndControl& sc,
588 const DebugDrawerInterfacePrx& drawer,
589 const DebugObserverInterfacePrx& debugObs)
590 {
592 if (coll)
593 {
594 for (auto& pair : coll->collLimb)
595 {
596 collLimbPublish(pair.second, debugObs);
597 }
598 }
599 }
600
601 void
603 {
605 "rt Preactivate controller NJointTaskspaceCollisionAvoidanceImpedanceController");
608 if (collReady.load())
609 {
611 coll->rtPreActivate();
612 }
613 }
614
615 void
617 {
619 if (collReady.load())
620 {
622 coll->rtPostDeactivate();
623 }
625 "post deactivate: NJointTaskspaceCollisionAvoidanceImpedanceController");
626 }
627
630 const VirtualRobot::RobotPtr& robot,
631 const std::map<std::string, ConstControlDevicePtr>& controlDevices,
632 const std::map<std::string, ConstSensorDevicePtr>&)
633 {
634 using namespace armarx::WidgetDescription;
635 HBoxLayoutPtr layout = new HBoxLayout;
636
637
638 ::armarx::WidgetDescription::WidgetSeq widgets;
639
640 /// select default config
641 LabelPtr label = new Label;
642 label->text = "select a controller config";
643
644 StringComboBoxPtr cfgBox = new StringComboBox;
645 cfgBox->name = "config_box";
646 cfgBox->defaultIndex = 0;
647 cfgBox->multiSelect = false;
648
649 cfgBox->options =
650 std::vector<std::string>{"default", "default_a7_right", "default_a7_right_zero_torque"};
652
653 layout->children.emplace_back(label);
654 layout->children.emplace_back(cfgBox);
656
657 layout->children.insert(layout->children.end(), widgets.begin(), widgets.end());
658 ARMARX_INFO_S << "Layout done";
659 return layout;
660 }
661
664 const StringVariantBaseMap& values)
665 {
666 auto cfgName = values.at("config_box")->getString();
667 const armarx::PackagePath configPath(
668 "armarx_control",
669 "controller_config/NJointTaskspaceCollisionAvoidanceImpedanceController/" + cfgName +
670 ".json");
671 ARMARX_INFO_S << "Loading config from " << configPath.toSystemPath();
672 ARMARX_CHECK(std::filesystem::exists(configPath.toSystemPath()));
673
674 auto cfgDTO = armarx::readFromJson<CollisionCtrlCfg>(configPath.toSystemPath());
675
677 return new ConfigurableNJointControllerConfig{cfgDTO.toAronDTO()};
678 }
679
680} // namespace armarx::control::njoint_controller::task_space
#define ARMARX_RT_LOGF_WARN(...)
#define ARMARX_RT_LOGF_INFO(...)
const VirtualRobot::RobotPtr & rtGetRobot()
TODO make protected and use attorneys.
static std::filesystem::path toSystemPath(const data::PackagePath &pp)
const T & getUpToDateReadBuffer() const
The Variant class is described here: Variants.
Definition Variant.h:224
static WidgetDescription::WidgetPtr GenerateConfigDescription(const VirtualRobot::RobotPtr &, const std::map< std::string, ConstControlDevicePtr > &, const std::map< std::string, ConstSensorDevicePtr > &)
NJointTaskspaceCollisionAvoidanceImpedanceController(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &robot)
void updateCollisionAvoidanceConfig(const ::armarx::aron::data::dto::DictPtr &dto, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
NJointController interface for collision avoidance.
void rtRun(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration) override
TODO make protected and use attorneys.
void collLimbPublish(core::CollisionAvoidanceBase::NodeSetData &arm, const DebugObserverInterfacePrx &debugObs)
void onPublish(const SensorAndControl &sc, const DebugDrawerInterfacePrx &drawer, const DebugObserverInterfacePrx &) override
void updateConfig(const ::armarx::aron::data::dto::DictPtr &dto, const Ice::Current &iceCurrent) override
void onPublish(const SensorAndControl &, const DebugDrawerInterfacePrx &, const DebugObserverInterfacePrx &) override
::armarx::aron::data::dto::DictPtr getConfig(const Ice::Current &iceCurrent=Ice::emptyCurrent) override
NJointTaskspaceImpedanceController(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &)
void rtPostDeactivateController() override
This function is called after the controller is deactivated.
void updateConfig(const ::armarx::aron::data::dto::DictPtr &dto, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
NJointController interface.
void rtPreActivateController() override
This function is called before the controller is activated.
void limbRTUpdateStatus(ArmPtr &arm, const double deltaT)
-----------------------------— Real time cotnrol --------------------------------------—
#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(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_INFO_S
Definition Logging.h:202
armarx::aron::data::dto::Dict getCollisionAvoidanceConfig()
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
::IceInternal::Handle<::armarx::WidgetDescription::Widget > WidgetPtr
::IceInternal::Handle< Dict > DictPtr
void debugEigenVec(StringVariantBaseMap &datafields, const std::string &name, Eigen::VectorXf vec)
Definition utils.cpp:190
NJointControllerRegistration< NJointTaskspaceCollisionAvoidanceImpedanceController > registrationControllerNJointTaskspaceCollisionAvoidanceImpedanceController("NJointTaskspaceCollisionAvoidanceImpedanceController")
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugObserverInterface > DebugObserverInterfacePrx
std::map< std::string, VariantBasePtr > StringVariantBaseMap
AronDTO readFromJson(const std::filesystem::path &filename)
IceUtil::Handle< class RobotUnit > RobotUnitPtr
Definition FTSensor.h:34
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugDrawerInterface > DebugDrawerInterfacePrx
detail::ControlThreadOutputBufferEntry SensorAndControl
#define ARMARX_TRACE
Definition trace.h:77