MPPool.cpp
Go to the documentation of this file.
1#include "MPPool.h"
2
3#include <SimoxUtility/json.h>
4#include <VirtualRobot/Nodes/RobotNode.h>
5
8
12#include <armarx/control/common/mp/aron/MPConfig.aron.generated.h>
13
14#include "../utils.h"
15#include "JSMP.h"
16#include "KeypointsMP.h"
17#include "TSMP.h"
18
20{
21
22 void
23 MPPool::createMPs(const MPListConfig& mpListConfig)
24 {
25 auto start = IceUtil::Time::now().toSecondsDouble();
26 ARMARX_INFO << "----------------------------------- creating MPs "
27 "-------------------------------------------------";
28 ARMARX_INFO << " -- in MPPool, we have " << mpListConfig.mpList.size() << " MPs";
29 phaseStops_.clear();
30
31 int index = 0;
32 for (const MPConfig& c : mpListConfig.mpList)
33 {
34 auto className = mpClass::_from_string_nocase(c.className.c_str());
35 ARMARX_INFO << "-- (" << index << ") creating MP with name " << c.name
36 << "\n---- class: " << c.className << "\n---- type: " << c.mpTypeString
37 << "\n---- mode: " << c.mpMode << "\n---- style: " << c.mpStyle
38 << "\n---- group: " << c.group.toString()
39 << (c.enablePhaseStop ? "\n---- phase stop active " : "");
40 index++;
41 phaseStops_.try_emplace(c.group, PhaseStopResult{});
42 switch (className)
43 {
44 case mpClass::JSMP:
45 {
46 JSMPPtr jsmp(new JSMP(c));
47 JSMPInputPtr in(new JSMPInput());
48 JSMPOutputPtr out(new JSMPOutput());
49 mps.insert({c.name, {jsmp, in, out}});
50 break;
51 }
52 case mpClass::JSVelMP:
53 break;
54 case mpClass::TSMP:
55 {
56 TSMPPtr tsmp(new TSMP(c));
57 TSMPInputPtr in(new TSMPInput());
58 TSMPOutputPtr out(new TSMPOutput());
59 mps.insert({c.name, {tsmp, in, out}});
60
61 break;
62 }
63 case mpClass::KeypointsMP:
64 {
65 KeypointsMPPtr tsmp(new KeypointsMP(c));
68 mps.insert({c.name, {tsmp, in, out}});
69 break;
70 }
71 case mpClass::TSVelMP:
72 break;
73 default:
74 ARMARX_WARNING << "unsupported MP class: " << c.className
75 << "\nsupported names include: "
76 "JSMP, JSVelMP, TSMP, TSVelMP, KeypointsMP";
77 break;
78 }
79 }
80 auto duration = IceUtil::Time::now().toSecondsDouble() - start;
81 std::string allGroups;
82 for (auto& pair : phaseStops_)
83 {
84 if (not allGroups.empty())
85 {
86 allGroups += ", ";
87 }
88 allGroups += pair.first.toString();
89 }
90 ARMARX_INFO << "-- created phase stop variables for groups: " << allGroups;
91 ARMARX_INFO << "---------------------------------- All MPs created in " << duration
92 << " sec "
93 "-----------------------------------------------";
94 }
95
96 void
97 MPPool::reconfigureMPs(const MPListConfig& mpListConfig)
98 {
99 mps.clear();
100 createMPs(mpListConfig);
101 }
102
103 void
104 MPPool::runMPs(const bool rtSafe)
105 {
106 // std::map<std::string, PhaseStopResult> phaseStops;
107 /// Since there may be MPs for TCP, posture and fingers, we group those for one arm to use
108 /// the same phase stop signal, usually it is a good choice to use the Task Space MP to
109 /// compute the phase stop signal and propagate this to other mps in the same group
110 /// Compute phase stop
111 for (auto& mp : mps)
112 {
113 if ((rtSafe or mp.second.mp->isFirstRun()) and mp.second.mp->isTaskSpaceMP())
114 {
115 auto& phaseStop = phaseStops_.at(mp.second.mp->getGroup());
116 mp.second.mp->computePhaseStop(mp.second.input, mp.second.output, phaseStop);
117 }
118 }
119
120 /// propagate phase top to other mps
121 for (auto& mp : mps)
122 {
123 if (rtSafe or mp.second.mp->isFirstRun())
124 {
125 auto& phaseStop = phaseStops_.at(mp.second.mp->getGroup());
126 mp.second.mp->run(mp.second.input, mp.second.output, phaseStop);
127 }
128 }
129 }
130
131 std::string
132 MPPool::getNames(const Ice::Current& /*iceCurrent*/)
133 {
134 std::string allMPs = "";
135 for (const auto& mp : mps)
136 {
137 if (!allMPs.empty())
138 {
139 allMPs += ", ";
140 }
141 allMPs += mp.second.mp->getMPName();
142 }
143 return allMPs;
144 }
145
146 void
147 MPPool::set(const ::armarx::StringDoubleSeqMap& startVec,
148 const ::armarx::StringDoubleSeqMap& goalVec,
149 const ::armarx::StringDoubleMap& durationSec,
150 const ::Ice::Current& /*unused*/)
151 {
152 for (auto& pair : mps)
153 {
154 auto it = durationSec.find(pair.first);
155 auto is = startVec.find(pair.first);
156 auto ig = goalVec.find(pair.first);
157
158 if (it != durationSec.end())
159 {
160 if (it->second > 0.0)
161 {
162 pair.second.mp->setDurationSec(it->second);
163 }
164 }
165 if (is != startVec.end())
166 {
167 pair.second.mp->setStart(is->second);
168 }
169 if (ig != goalVec.end())
170 {
171 pair.second.mp->setGoal(ig->second);
172 }
173 }
174 }
175
176 void
177 MPPool::startAll(const Ice::Current& /*iceCurrent*/)
178 {
179 start();
180 }
181
182 void
183 MPPool::start(const std::string& mpName,
184 const DVec& startVec,
185 const DVec& goalVec,
186 Ice::Double timeDuration,
187 const Ice::Current& /*iceCurrent*/)
188 {
189 auto start = IceUtil::Time::now().toSecondsDouble();
190 if (mpName == "all")
191 {
192 ARMARX_INFO << "--------------------------------------- start all MPs "
193 "---------------------------------------";
194 ARMARX_INFO << " -- To start all MPs at once, it's up to the user to configure the "
195 "start, goal and timeduration properly before this call.";
196 int index = 0;
197 for (auto& mp : mps)
198 {
199 ARMARX_INFO << " -- (" << index << ")-th MP: ";
200 mp.second.mp->start();
201 index++;
202 }
203 ARMARX_INFO << " -- all MPs started.";
204 }
205 else
206 {
207 auto search = mps.find(mpName);
208 if (search != mps.end())
209 {
210 if (timeDuration < 0.0)
211 {
212 search->second.mp->start(goalVec, startVec);
213 }
214 else
215 {
216 search->second.mp->start(goalVec, startVec, timeDuration);
217 }
218 }
219 else
220 {
221 ARMARX_ERROR << mpName
222 << " is not in the MP pool. Please check your configuration file";
223 }
224 }
225 // ARMARX_IMPORTANT << "starting mp" << VAROUT(mpName) << "with start: " << dVecToString(startVec) << " and goal: " << dVecToString(goalVec) << " for " << timeDuration << " seconds";
226 auto duration = IceUtil::Time::now().toSecondsDouble() - start;
227 ARMARX_INFO << "All mp started in " << duration << " sec.";
228 }
229
230 void
231 MPPool::stopAll(const Ice::Current& /*iceCurrent*/)
232 {
233 stop();
234 }
235
236 void
237 MPPool::requestStop(const std::string& mpName, const Ice::Current& /*unused*/)
238 {
239 if (mpName == "all")
240 {
241 for (auto& mp : mps)
242 {
243 mp.second.mp->requestStop();
244 }
245 }
246 else
247 {
248 auto search = mps.find(mpName);
249 if (search != mps.end())
250 {
251 search->second.mp->requestStop();
252 }
253 else
254 {
255 ARMARX_ERROR << mpName
256 << " is not in the MP pool. Please check your configuration file";
257 }
258 }
259 }
260
261 void
262 MPPool::stop(const std::string& mpName, const Ice::Current& /*unused*/)
263 {
264 if (mpName == "all")
265 {
266 for (auto& mp : mps)
267 {
268 mp.second.mp->stop();
269 }
270 }
271 else
272 {
273 auto search = mps.find(mpName);
274 if (search != mps.end())
275 {
276 search->second.mp->stop();
277 }
278 else
279 {
280 ARMARX_ERROR << mpName
281 << " is not in the MP pool. Please check your configuration file";
282 }
283 }
284 }
285
286 void
287 MPPool::pauseAll(const Ice::Current& /*iceCurrent*/)
288 {
289 pause();
290 }
291
292 void
293 MPPool::pause(const std::string& mpName, const Ice::Current& /*unused*/)
294 {
295 if (mpName == "all")
296 {
297 for (auto& mp : mps)
298 {
299 mp.second.mp->pause();
300 }
301 }
302 else
303 {
304 auto search = mps.find(mpName);
305 if (search != mps.end())
306 {
307 search->second.mp->pause();
308 }
309 else
310 {
311 ARMARX_ERROR << mpName
312 << " is not in the MP pool. Please check your configuration file";
313 }
314 }
315 }
316
317 void
318 MPPool::resumeAll(const Ice::Current& /*iceCurrent*/)
319 {
320 resume();
321 }
322
323 void
324 MPPool::resume(const std::string& mpName, const Ice::Current& /*unused*/)
325 {
326 if (mpName == "all")
327 {
328 for (auto& mp : mps)
329 {
330 mp.second.mp->resume();
331 }
332 }
333 else
334 {
335 auto search = mps.find(mpName);
336 if (search != mps.end())
337 {
338 search->second.mp->resume();
339 }
340 else
341 {
342 ARMARX_ERROR << mpName
343 << " is not in the MP pool. Please check your configuration file";
344 }
345 }
346 }
347
348 void
349 MPPool::resetAll(const Ice::Current& /*iceCurrent*/)
350 {
351 reset();
352 }
353
354 void
355 MPPool::reset(const std::string& mpName, const Ice::Current& /*unused*/)
356 {
357 if (mpName == "all")
358 {
359 for (auto& mp : mps)
360 {
361 mp.second.mp->reset();
362 }
363 }
364 else
365 {
366 auto search = mps.find(mpName);
367 if (search != mps.end())
368 {
369 search->second.mp->reset();
370 }
371 else
372 {
373 ARMARX_ERROR << mpName
374 << " is not in the MP pool. Please check your configuration file";
375 }
376 }
377 }
378
379 bool
380 MPPool::isFinishedAll(const Ice::Current& /*iceCurrent*/)
381 {
382 return isFinished();
383 }
384
385 bool
386 MPPool::isFinished(const std::string& mpName, const Ice::Current& /*unused*/)
387 {
388 if (mpName == "all")
389 {
390 return std::all_of(mps.begin(),
391 mps.end(),
392 [](const auto& pair) { return pair.second.mp->isFinished(); });
393 }
394
395 auto it = mps.find(mpName);
396 if (it != mps.end())
397 {
398 return it->second.mp->isFinished();
399 }
400
401 ARMARX_ERROR << mpName << " is not in the MP pool. Please check your configuration file";
402 return true;
403 }
404
405 void
406 MPPool::learnFromCSV(const Ice::StringSeq& fileNames, const Ice::Current& /*iceCurrent*/)
407 {
408 if (!fileNames.empty())
409 {
410 ARMARX_WARNING << "Be aware that the fileNames ice parameter is not yet used. "
411 << "Instead, set the file names in the MPConfig parameter of your "
412 << "previous ice interface call.";
413 }
414 ARMARX_INFO << "--------------------------------------- Train MPs "
415 "----------------------------------------------------";
416 for (auto& mp : mps)
417 {
418 mp.second.mp->learnFromCSV();
419 }
420 isMPReady.store(true);
421 ARMARX_INFO << "--------------------------------------- done "
422 "----------------------------------------------------";
423 }
424
425 void
426 MPPool::learnFromTrajs(const ::armarx::aron::data::dto::DictPtr& dict,
427 const Ice::Current& /*iceCurrent*/)
428 {
429 auto start = IceUtil::Time::now().toSecondsDouble();
430 ARMARX_INFO << "--------------------------------------- Train MPs "
431 "----------------------------------------------------";
432
433 // Convert parameter of ice interface call to business object
434 MultiMPTrajs trajsDict;
435 trajsDict.fromAron(dict);
436 // std::map<std::string, std::vector<arondto::MPTraj>> dto =
437 // arondto::MultiMPTrajs::FromAron(dict).data;
438 // // armarx::aron::fromAron<std::vector<arondto::MPTraj>, MPTrajs>(arondto::MultiMPTrajs::FromAron(dict), bo);
439 // armarx::aron::fromAron<std::string, std::vector<arondto::MPTraj>, std::string, MPTrajs>(
440 // dto, trajsDict);
441
442 // MultiMPTrajs trajsDict = ::armarx::fromAronDict<arondto::MultiMPTrajs, MultiMPTrajs>(dict);
443
444 if (trajsDict.data.empty())
445 {
446 ARMARX_INFO << "Learning from trajectories specified in MPConfig(s) rather than as an "
447 "ice parameter";
448 for (const auto& [mpName, mpInputOutput] : mps)
449 {
450 const auto& mpConfig = mpInputOutput.mp->getConfig();
451 ARMARX_CHECK(not mpConfig.trajectoryList.empty())
452 << "For MP " << mpName << ": No trajectories provided as parameter, "
453 << "and not trajectories specified in MPConfig.";
454 mpInputOutput.mp->learnFromTraj(mpConfig.trajectoryList);
455 }
456 }
457 else
458 {
459 for (const auto& [mpName, trajs] : trajsDict.data)
460 {
461 // Learn the MP identified by mpName from the trajectory list stored in
462 // trajsDict.at(mpName)
463 ARMARX_CHECK(mps.count(mpName))
464 << "Trajectories provided for unknown MP " << mpName;
465 ARMARX_CHECK(not trajs.empty())
466 << "Empty list of trajectories provided for MP " << mpName;
467 mps.at(mpName).mp->learnFromTraj(trajs);
468 }
469 }
470 // mark whole MP pool as ready
471 isMPReady.store(true);
472
473 auto duration = IceUtil::Time::now().toSecondsDouble() - start;
474 ARMARX_INFO << "--------------------------------------- done in " << duration
475 << " sec "
476 "----------------------------------------------------";
477 }
478
479 void
480 MPPool::trainMP(const Ice::Current& /*iceCurrent*/)
481 {
482 auto start = IceUtil::Time::now().toSecondsDouble();
483 for (auto& mp : mps)
484 {
485 mp.second.mp->trainMP();
486 }
487 isMPReady.store(true);
488 auto duration = IceUtil::Time::now().toSecondsDouble() - start;
489 ARMARX_INFO << "training finished in " << duration << " sec.";
490 }
491
492 void
493 MPPool::setGoal(const DVec& /*goals*/, const Ice::Current& /*iceCurrent*/)
494 {
495 }
496
497 void
499 const DVec& goals,
500 const Ice::Current& /*iceCurrent*/)
501 {
502 for (auto& mp : mps)
503 {
504 mp.second.mp->setStartAndGoal(starts, goals);
505 }
506 }
507
508 void
509 MPPool::setViaPoint(Ice::Double /*u*/,
510 const DVec& /*viapoint*/,
511 const Ice::Current& /*iceCurrent*/)
512 {
513 }
514
515 void
516 MPPool::removeAllViaPoint(const Ice::Current& /*iceCurrent*/)
517 {
518 }
519
520 //void MPPool::setWeight(const DVecSeq& weights, const Ice::Current &iceCurrent)
521 //{
522
523 //}
524
525 std::string
526 MPPool::serialize(const Ice::Current& /*iceCurrent*/)
527 {
528 return "";
529 }
530
531 DVec
532 MPPool::deserialize(const std::string& /*unused*/, const Ice::Current& /*iceCurrent*/)
533 {
534 std::vector<double> test{0.1, 0.1};
535 return test;
536 }
537
538 Ice::Double
539 MPPool::getCanVal(const std::string& mpName, const Ice::Current& /*iceCurrent*/)
540 {
541 auto search = mps.find(mpName);
542 if (search != mps.end())
543 {
544 return search->second.mp->getCanonicalValue();
545 }
546 ARMARX_ERROR << mpName << " is not in the MP pool. Please check your configuration file";
547 return 1.0;
548 }
549
550 bool
551 MPPool::getMPEnabled(const Ice::Current& /*unused*/)
552 {
553 return true;
554 }
555
556 void
557 MPPool::updateMPConfig(const ::armarx::aron::data::dto::DictPtr& /*dto*/,
558 const Ice::Current& /*iceCurrent*/)
559 {
560 ARMARX_WARNING << "You should overwrite this method in your concrete MP controllers, and "
561 "call resetMPs(dto, rnsMap)";
562 }
563
564 bool
565 MPPool::resetMPs(const ::armarx::aron::data::dto::DictPtr& dto,
566 const std::map<std::string, VirtualRobot::RobotNodeSetPtr>& rnsMap)
567 {
568 std::scoped_lock lock(mtx_mps);
569 if (not isFinishedAll())
570 {
571 ARMARX_WARNING << "MP is not finished yet, cannot reset MP\n"
572 "If you want to force reset, please call \n\n"
573 " ctrl->stop('all') \n\n"
574 "before you continue";
575 return false;
576 }
577
578 auto configData = MPListConfig::FromAron(dto);
579 isMPReady.store(false);
580 while (mpTaskRunning.load())
581 {
582 usleep(1000);
583 }
584
585 for (const auto& mp : configData.mpList)
586 {
587 if (rnsMap.find(mp.nodeSetName) == rnsMap.end())
588 {
589 ARMARX_WARNING << "You have to make sure the RobotNodeSet " << mp.nodeSetName
590 << " in your MP config "
591 << "corresponds to one of the RobotNodeSet in the controllers";
592 return false;
593 }
594 }
595 mpConfig = configData;
597
599 ARMARX_INFO << "-- successfully updated MP config.";
600 return true;
601 }
602
603 bool
604 MPPool::resetMPsV1(const ::armarx::aron::data::dto::DictPtr& dto,
605 const std::map<std::string, VirtualRobot::RobotNodeSetPtr>& rnsMap,
606 const std::shared_ptr<common::coordination::Coordination>& coordinator)
607 {
608 const std::scoped_lock lock(mtx_mps);
609 if (not isFinishedAll())
610 {
611 ARMARX_WARNING << "MP is not finished yet, cannot reset MP\n"
612 "If you want to force reset, please call \n\n"
613 " ctrl->stop('all') \n\n"
614 "before you continue";
615 return false;
616 }
617
618 auto configData = MPListConfig::FromAron(dto);
619 isMPReady.store(false);
620 while (mpTaskRunning.load())
621 {
622 usleep(1000);
623 }
624
625 if (coordinator)
626 {
627 if (not coordinator->isInitialized())
628 {
629 usleep(1000);
630 ARMARX_WARNING << "Coordinator is not yet initialized.";
631 return false;
632 }
633 for (const auto& nodeSetName : coordinator->getNodesetList())
634 {
635 if (rnsMap.find(nodeSetName) == rnsMap.end())
636 {
638 << "Requested RobotNodeSet " << nodeSetName
639 << " by coordinator does not exist in the controller. MP won't be created!";
640 return false;
641 }
642 }
643 }
644 else
645 {
646 for (const auto& mp : configData.mpList)
647 {
648 if (rnsMap.find(mp.nodeSetName) == rnsMap.end())
649 {
650 ARMARX_WARNING << "You have to make sure the RobotNodeSet " << mp.nodeSetName
651 << " in your MP config "
652 << "corresponds to one of the RobotNodeSet in the controllers";
653 return false;
654 }
655 }
656 }
657 mpConfig = configData;
659
660 reInitMPInputOutputDataV1(rnsMap, coordinator);
661 ARMARX_INFO << "-- successfully updated MP config.";
662 return true;
663 }
664
665 bool
666 MPPool::resetMPsV2(const ::armarx::aron::data::dto::DictPtr& dto,
667 const std::map<std::string, MPReInitData>& data)
668 {
669 const std::scoped_lock lock(mtx_mps);
670 if (not isFinishedAll())
671 {
672 ARMARX_WARNING << "MP is not finished yet, cannot reset MP\n"
673 "If you want to force reset, please call \n\n"
674 " ctrl->stop('all') \n\n"
675 "before you continue";
676 return false;
677 }
678
679 auto configData = MPListConfig::FromAron(dto);
680 isMPReady.store(false);
681 while (mpTaskRunning.load())
682 {
683 usleep(1000);
684 }
685
686 for (const auto& mp : configData.mpList)
687 {
688 if (data.find(mp.nodeSetName) == data.end())
689 {
690 ARMARX_WARNING << "You have to make sure the RobotNodeSet " << mp.nodeSetName
691 << " in your MP config "
692 << "corresponds to one of the RobotNodeSet in the controllers";
693 return false;
694 }
695 }
696 mpConfig = configData;
698
700 ARMARX_INFO << "-- successfully updated MP config.";
701 return true;
702 }
703
705 MPPool::getMPConfig(const Ice::Current& /*iceCurrent*/)
706 {
707 return mpConfig.toAronDTO();
708 }
709
710 void
711 MPPool::reInitMPInputOutputDataV2(const std::map<std::string, MPReInitData>& data)
712 {
713 ARMARX_INFO << "-- reconfigure MP: reinitialize the mp input output, as well as the rt "
714 "related buffer values";
715 int index = 0;
716 for (auto& mp : mps)
717 {
718 // const auto& nodeSetName = ;
719 // ARMARX_CHECK_EQUAL(nodeSetName, limb.at(nodeSetName)->kinematicChainName);
720 const auto& d = data.at(mp.second.mp->getNodeSetName());
721 const auto& role = mp.second.mp->getRole();
722 if (role == "taskspace" or role == "object")
723 {
724 ARMARX_CHECK_EQUAL(d.pos.size(), 7)
725 << "the task space pos must have 7 dimensions, got " << d.pos.size();
726 // ARMARX_CHECK_EQUAL(d.vel.size(), 6)
727 // << "the task space velocity must have 6 dimensions, got " << d.vel.size();
728 const Eigen::Matrix4f currentPose = common::vec7fToMat4f(d.pos);
729 ARMARX_INFO << "---- (" << index << ") init input output data for "
730 << mp.second.mp->getMPName();
731 std::dynamic_pointer_cast<mp::TSMPInput>(mp.second.input)->pose = currentPose;
732 std::dynamic_pointer_cast<mp::TSMPInput>(mp.second.input)->vel.setZero();
733 std::dynamic_pointer_cast<mp::TSMPOutput>(mp.second.output)->pose = currentPose;
734 std::dynamic_pointer_cast<mp::TSMPOutput>(mp.second.output)->vel.setZero();
735 }
736 else if (role == "nullspace" or role == "hand")
737 {
738 ARMARX_INFO << "---- (" << index << ") init input output data for "
739 << mp.second.mp->getMPName() << " with " << d.pos.size() << " joints";
740 std::dynamic_pointer_cast<mp::JSMPInput>(mp.second.input)->angleRadian = d.pos;
741 std::dynamic_pointer_cast<mp::JSMPInput>(mp.second.input)->angularVel = d.vel;
742 std::dynamic_pointer_cast<mp::JSMPOutput>(mp.second.output)->angleRadian = d.pos;
743 std::dynamic_pointer_cast<mp::JSMPOutput>(mp.second.output)->angularVel = d.vel;
744 }
745 // else if (_mp.second.mp->getRole() == "hand")
746 // {
747 // ARMARX_INFO << "---- (" << index << ") init input output data for "
748 // << _mp.second.mp->getMPName() << " with "
749 // << d.pos.size() << " joints";
750 // std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input)->angleRadian = d.pos;
751 // std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input)->angularVel = d.vel;
752 // std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output)->angleRadian = d.pos;
753 // std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output)->angularVel = d.vel;
754 // }
755 index++;
756 }
757 }
758
759 void
761 const std::map<std::string, VirtualRobot::RobotNodeSetPtr>& rnsMap)
762 {
763 ARMARX_INFO << "-- reconfigure MP: reinitialize the mp input output, as well as the rt "
764 "related buffer values";
765 int index = 0;
766 for (auto& mp : mps)
767 {
768 // const auto& nodeSetName = ;
769 // ARMARX_CHECK_EQUAL(nodeSetName, limb.at(nodeSetName)->kinematicChainName);
770 const VirtualRobot::RobotNodeSetPtr& rns = rnsMap.at(mp.second.mp->getNodeSetName());
771
772 if (mp.second.mp->getRole() == "taskspace")
773 {
774 Eigen::Matrix4f currentPose = rns->getTCP()->getPoseInRootFrame();
775 ARMARX_INFO << "---- (" << index << ") init input output data for "
776 << mp.second.mp->getMPName();
777 std::dynamic_pointer_cast<mp::TSMPInput>(mp.second.input)->pose = currentPose;
778 std::dynamic_pointer_cast<mp::TSMPInput>(mp.second.input)->vel.setZero();
779 std::dynamic_pointer_cast<mp::TSMPOutput>(mp.second.output)->pose = currentPose;
780 std::dynamic_pointer_cast<mp::TSMPOutput>(mp.second.output)->vel.setZero();
781 }
782 else if (mp.second.mp->getRole() == "nullspace")
783 {
784 ARMARX_INFO << "---- (" << index << ") init input output data for "
785 << mp.second.mp->getMPName() << " with " << rns->getJointValues().size()
786 << " joints";
787 std::dynamic_pointer_cast<mp::JSMPInput>(mp.second.input)->angleRadian =
788 rns->getJointValuesEigen();
789 std::dynamic_pointer_cast<mp::JSMPInput>(mp.second.input)->angularVel =
790 Eigen::VectorXf::Zero(rns->getJointValues().size());
791 std::dynamic_pointer_cast<mp::JSMPOutput>(mp.second.output)->angleRadian =
792 rns->getJointValuesEigen();
793 std::dynamic_pointer_cast<mp::JSMPOutput>(mp.second.output)->angularVel =
794 Eigen::VectorXf::Zero(rns->getJointValues().size());
795 }
796 else if (mp.second.mp->getRole() == "hand")
797 {
798 ARMARX_INFO << "---- (" << index << ") init input output data for "
799 << mp.second.mp->getMPName() << " with " << rns->getJointValues().size()
800 << " joints";
801 std::dynamic_pointer_cast<mp::JSMPInput>(mp.second.input)->angleRadian =
802 rns->getJointValuesEigen();
803 std::dynamic_pointer_cast<mp::JSMPInput>(mp.second.input)->angularVel =
804 Eigen::VectorXf::Zero(rns->getJointValues().size());
805 std::dynamic_pointer_cast<mp::JSMPOutput>(mp.second.output)->angleRadian =
806 rns->getJointValuesEigen();
807 std::dynamic_pointer_cast<mp::JSMPOutput>(mp.second.output)->angularVel =
808 Eigen::VectorXf::Zero(rns->getJointValues().size());
809 }
810 index++;
811 }
812 }
813
814 void
816 const std::map<std::string, VirtualRobot::RobotNodeSetPtr>& rnsMap,
817 const std::shared_ptr<common::coordination::Coordination>& coordinator)
818 {
819 ARMARX_INFO << "-- reconfigure MP: reinitialize the mp input output, as well as the rt "
820 "related buffer values";
821 int index = 0;
822 for (auto& mp : mps)
823 {
824 const auto& role = mp.second.mp->getRole();
825 // const auto& nodeSetName = ;
826 // ARMARX_CHECK_EQUAL(nodeSetName, limb.at(nodeSetName)->kinematicChainName);
827
828 if (role == "taskspace")
829 {
830 const VirtualRobot::RobotNodeSetPtr& rns =
831 rnsMap.at(mp.second.mp->getNodeSetName());
832 const Eigen::Matrix4f currentPose = rns->getTCP()->getPoseInRootFrame();
833 ARMARX_INFO << "---- (" << index << ") init input output data for "
834 << mp.second.mp->getMPName();
835 std::dynamic_pointer_cast<mp::TSMPInput>(mp.second.input)->pose = currentPose;
836 std::dynamic_pointer_cast<mp::TSMPInput>(mp.second.input)->vel.setZero();
837 std::dynamic_pointer_cast<mp::TSMPOutput>(mp.second.output)->pose = currentPose;
838 std::dynamic_pointer_cast<mp::TSMPOutput>(mp.second.output)->vel.setZero();
839 }
840 else if (role == "object")
841 {
842 ARMARX_CHECK_NOT_NULL(coordinator)
843 << "When MP role is object, the coordinator must be active";
844 ARMARX_CHECK(coordinator->isInitialized())
845 << "The coordinator must first be initialized.";
846
847 const auto& coord =
848 std::dynamic_pointer_cast<common::coordination::SyncCoordination>(coordinator);
849 const std::scoped_lock lock(coord->mtx_data_non_rt);
850 const Eigen::Matrix4f currentPose = coord->dataNonRt.targetPose;
851
852 std::dynamic_pointer_cast<mp::TSMPInput>(mp.second.input)->pose = currentPose;
853 std::dynamic_pointer_cast<mp::TSMPInput>(mp.second.input)->vel.setZero();
854 std::dynamic_pointer_cast<mp::TSMPOutput>(mp.second.output)->pose = currentPose;
855 std::dynamic_pointer_cast<mp::TSMPOutput>(mp.second.output)->vel.setZero();
856 }
857 else if (role == "nullspace" or role == "hand")
858 {
859 const VirtualRobot::RobotNodeSetPtr& rns =
860 rnsMap.at(mp.second.mp->getNodeSetName());
861 ARMARX_INFO << "---- (" << index << ") init input output data for "
862 << mp.second.mp->getMPName() << " with " << rns->getJointValues().size()
863 << " joints";
864 std::dynamic_pointer_cast<mp::JSMPInput>(mp.second.input)->angleRadian =
865 rns->getJointValuesEigen();
866 std::dynamic_pointer_cast<mp::JSMPInput>(mp.second.input)->angularVel =
867 Eigen::VectorXf::Zero(rns->getJointValues().size());
868 std::dynamic_pointer_cast<mp::JSMPOutput>(mp.second.output)->angleRadian =
869 rns->getJointValuesEigen();
870 std::dynamic_pointer_cast<mp::JSMPOutput>(mp.second.output)->angularVel =
871 Eigen::VectorXf::Zero(rns->getJointValues().size());
872 }
873 else
874 {
875 ARMARX_WARNING << "MP of role " << role << " is not supported!";
876 }
877 index++;
878 }
879 }
880
881} // namespace armarx::control::common::mp
uint8_t index
constexpr T c
bool resetMPs(const ::armarx::aron::data::dto::DictPtr &dto, const std::map< std::string, VirtualRobot::RobotNodeSetPtr > &rnsMap)
Definition MPPool.cpp:565
bool resetMPsV2(const ::armarx::aron::data::dto::DictPtr &dto, const std::map< std::string, MPReInitData > &data)
Definition MPPool.cpp:666
void learnFromTrajs(const ::armarx::aron::data::dto::DictPtr &dict, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition MPPool.cpp:426
void setGoal(const DVec &goals, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition MPPool.cpp:493
void resume(const std::string &mpName="all", const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition MPPool.cpp:324
void reconfigureMPs(const MPListConfig &mpListConfig)
Definition MPPool.cpp:97
bool resetMPsV1(const ::armarx::aron::data::dto::DictPtr &dto, const std::map< std::string, VirtualRobot::RobotNodeSetPtr > &rnsMap, const std::shared_ptr< common::coordination::Coordination > &coordinator)
Definition MPPool.cpp:604
std::recursive_mutex mtx_mps
Definition MPPool.h:147
Ice::Double getCanVal(const std::string &mpName, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition MPPool.cpp:539
bool isFinished(const std::string &mpName="all", const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition MPPool.cpp:386
void updateMPConfig(const ::armarx::aron::data::dto::DictPtr &dto, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition MPPool.cpp:557
void learnFromCSV(const Ice::StringSeq &fileNames=std::vector< std::string >(), const Ice::Current &iceCurrent=Ice::emptyCurrent) override
setting
Definition MPPool.cpp:406
void createMPs(const MPListConfig &mpListConfig)
Definition MPPool.cpp:23
void setStartAndGoal(const DVec &starts, const DVec &goals, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition MPPool.cpp:498
DVec deserialize(const std::string &, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition MPPool.cpp:532
void stop(const std::string &mpName="all", const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition MPPool.cpp:262
std::map< std::string, MPInputOutput > mps
Definition MPPool.h:146
void reInitMPInputOutputData(const std::map< std::string, VirtualRobot::RobotNodeSetPtr > &rnsMap)
Definition MPPool.cpp:760
MPListConfig mpConfig
this variable is only needed when constructing the MP instances, therefore you don't need to use trip...
Definition MPPool.h:153
void reInitMPInputOutputDataV2(const std::map< std::string, MPReInitData > &data)
Definition MPPool.cpp:711
void requestStop(const std::string &mpName="all", const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition MPPool.cpp:237
void start(const std::string &mpName="all", const DVec &startVec=std::vector< double >(), const DVec &goalVec=std::vector< double >(), Ice::Double timeDuration=-1.0, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
control
Definition MPPool.cpp:183
std::map< arondto::MPGroup, PhaseStopResult > phaseStops_
Definition MPPool.h:162
void setViaPoint(Ice::Double u, const DVec &viapoint, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition MPPool.cpp:509
void reset(const std::string &mpName="all", const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition MPPool.cpp:355
void reInitMPInputOutputDataV1(const std::map< std::string, VirtualRobot::RobotNodeSetPtr > &rnsMap, const std::shared_ptr< common::coordination::Coordination > &coordinator)
Definition MPPool.cpp:815
std::atomic< bool > isMPReady
Definition MPPool.h:148
void set(const ::armarx::StringDoubleSeqMap &, const ::armarx::StringDoubleSeqMap &, const ::armarx::StringDoubleMap &, const ::Ice::Current &iceCurrent=::Ice::emptyCurrent) override
Definition MPPool.cpp:147
void pause(const std::string &mpName="all", const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition MPPool.cpp:293
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#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_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
armarx::aron::data::dto::Dict getMPConfig()
string serialize()
serialze
::IceInternal::Handle< Dict > DictPtr
This file is part of ArmarX.
std::shared_ptr< TSMPOutput > TSMPOutputPtr
Definition TSMP.h:47
std::shared_ptr< KeypointsMPInput > KeypointsMPInputPtr
Definition KeypointsMP.h:45
Ice::DoubleSeq DVec
Definition MP.h:53
std::shared_ptr< TSMPInput > TSMPInputPtr
Definition TSMP.h:46
std::shared_ptr< JSMPOutput > JSMPOutputPtr
Definition JSMP.h:48
std::shared_ptr< KeypointsMPOutput > KeypointsMPOutputPtr
Definition KeypointsMP.h:46
std::shared_ptr< TSMP > TSMPPtr
Definition TSMP.h:67
std::shared_ptr< JSMP > JSMPPtr
Definition JSMP.h:61
std::shared_ptr< JSMPInput > JSMPInputPtr
Definition JSMP.h:47
std::shared_ptr< KeypointsMP > KeypointsMPPtr
Definition KeypointsMP.h:57
Eigen::Matrix4f vec7fToMat4f(const Eigen::VectorXf &vec)
Definition utils.cpp:340