3#include <SimoxUtility/json.h>
4#include <VirtualRobot/Nodes/RobotNode.h>
12#include <armarx/control/common/mp/aron/MPConfig.aron.generated.h>
25 auto start = IceUtil::Time::now().toSecondsDouble();
26 ARMARX_INFO <<
"----------------------------------- creating MPs "
27 "-------------------------------------------------";
28 ARMARX_INFO <<
" -- in MPPool, we have " << mpListConfig.mpList.size() <<
" MPs";
32 for (
const MPConfig&
c : mpListConfig.mpList)
34 auto className = mpClass::_from_string_nocase(
c.className.c_str());
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 " :
"");
49 mps.insert({
c.name, {jsmp, in, out}});
52 case mpClass::JSVelMP:
59 mps.insert({
c.name, {tsmp, in, out}});
63 case mpClass::KeypointsMP:
68 mps.insert({
c.name, {tsmp, in, out}});
71 case mpClass::TSVelMP:
75 <<
"\nsupported names include: "
76 "JSMP, JSVelMP, TSMP, TSVelMP, KeypointsMP";
80 auto duration = IceUtil::Time::now().toSecondsDouble() -
start;
81 std::string allGroups;
84 if (not allGroups.empty())
88 allGroups += pair.first.toString();
90 ARMARX_INFO <<
"-- created phase stop variables for groups: " << allGroups;
91 ARMARX_INFO <<
"---------------------------------- All MPs created in " << duration
93 "-----------------------------------------------";
113 if ((rtSafe or
mp.second.mp->isFirstRun()) and
mp.second.mp->isTaskSpaceMP())
116 mp.second.mp->computePhaseStop(
mp.second.input,
mp.second.output, phaseStop);
123 if (rtSafe or
mp.second.mp->isFirstRun())
126 mp.second.mp->run(
mp.second.input,
mp.second.output, phaseStop);
134 std::string allMPs =
"";
135 for (
const auto&
mp :
mps)
141 allMPs +=
mp.second.mp->getMPName();
148 const ::armarx::StringDoubleSeqMap& goalVec,
149 const ::armarx::StringDoubleMap& durationSec,
150 const ::Ice::Current& )
152 for (
auto& pair :
mps)
154 auto it = durationSec.find(pair.first);
155 auto is = startVec.find(pair.first);
156 auto ig = goalVec.find(pair.first);
158 if (it != durationSec.end())
160 if (it->second > 0.0)
162 pair.second.mp->setDurationSec(it->second);
165 if (is != startVec.end())
167 pair.second.mp->setStart(is->second);
169 if (ig != goalVec.end())
171 pair.second.mp->setGoal(ig->second);
184 const DVec& startVec,
186 Ice::Double timeDuration,
187 const Ice::Current& )
189 auto start = IceUtil::Time::now().toSecondsDouble();
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.";
200 mp.second.mp->start();
207 auto search =
mps.find(mpName);
208 if (search !=
mps.end())
210 if (timeDuration < 0.0)
212 search->second.mp->start(goalVec, startVec);
216 search->second.mp->start(goalVec, startVec, timeDuration);
222 <<
" is not in the MP pool. Please check your configuration file";
226 auto duration = IceUtil::Time::now().toSecondsDouble() -
start;
227 ARMARX_INFO <<
"All mp started in " << duration <<
" sec.";
243 mp.second.mp->requestStop();
248 auto search =
mps.find(mpName);
249 if (search !=
mps.end())
251 search->second.mp->requestStop();
256 <<
" is not in the MP pool. Please check your configuration file";
268 mp.second.mp->stop();
273 auto search =
mps.find(mpName);
274 if (search !=
mps.end())
276 search->second.mp->stop();
281 <<
" is not in the MP pool. Please check your configuration file";
299 mp.second.mp->pause();
304 auto search =
mps.find(mpName);
305 if (search !=
mps.end())
307 search->second.mp->pause();
312 <<
" is not in the MP pool. Please check your configuration file";
330 mp.second.mp->resume();
335 auto search =
mps.find(mpName);
336 if (search !=
mps.end())
338 search->second.mp->resume();
343 <<
" is not in the MP pool. Please check your configuration file";
361 mp.second.mp->reset();
366 auto search =
mps.find(mpName);
367 if (search !=
mps.end())
369 search->second.mp->reset();
374 <<
" is not in the MP pool. Please check your configuration file";
390 return std::all_of(
mps.begin(),
392 [](
const auto& pair) { return pair.second.mp->isFinished(); });
395 auto it =
mps.find(mpName);
398 return it->second.mp->isFinished();
401 ARMARX_ERROR << mpName <<
" is not in the MP pool. Please check your configuration file";
408 if (!fileNames.empty())
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.";
414 ARMARX_INFO <<
"--------------------------------------- Train MPs "
415 "----------------------------------------------------";
418 mp.second.mp->learnFromCSV();
421 ARMARX_INFO <<
"--------------------------------------- done "
422 "----------------------------------------------------";
427 const Ice::Current& )
429 auto start = IceUtil::Time::now().toSecondsDouble();
430 ARMARX_INFO <<
"--------------------------------------- Train MPs "
431 "----------------------------------------------------";
434 MultiMPTrajs trajsDict;
435 trajsDict.fromAron(dict);
444 if (trajsDict.data.empty())
446 ARMARX_INFO <<
"Learning from trajectories specified in MPConfig(s) rather than as an "
448 for (
const auto& [mpName, mpInputOutput] :
mps)
450 const auto&
mpConfig = mpInputOutput.mp->getConfig();
452 <<
"For MP " << mpName <<
": No trajectories provided as parameter, "
453 <<
"and not trajectories specified in MPConfig.";
454 mpInputOutput.mp->learnFromTraj(
mpConfig.trajectoryList);
459 for (
const auto& [mpName, trajs] : trajsDict.data)
464 <<
"Trajectories provided for unknown MP " << mpName;
466 <<
"Empty list of trajectories provided for MP " << mpName;
467 mps.at(mpName).mp->learnFromTraj(trajs);
473 auto duration = IceUtil::Time::now().toSecondsDouble() -
start;
474 ARMARX_INFO <<
"--------------------------------------- done in " << duration
476 "----------------------------------------------------";
482 auto start = IceUtil::Time::now().toSecondsDouble();
485 mp.second.mp->trainMP();
488 auto duration = IceUtil::Time::now().toSecondsDouble() -
start;
489 ARMARX_INFO <<
"training finished in " << duration <<
" sec.";
500 const Ice::Current& )
504 mp.second.mp->setStartAndGoal(starts, goals);
511 const Ice::Current& )
534 std::vector<double> test{0.1, 0.1};
541 auto search =
mps.find(mpName);
542 if (search !=
mps.end())
544 return search->second.mp->getCanonicalValue();
546 ARMARX_ERROR << mpName <<
" is not in the MP pool. Please check your configuration file";
558 const Ice::Current& )
560 ARMARX_WARNING <<
"You should overwrite this method in your concrete MP controllers, and "
561 "call resetMPs(dto, rnsMap)";
566 const std::map<std::string, VirtualRobot::RobotNodeSetPtr>& rnsMap)
568 std::scoped_lock lock(
mtx_mps);
572 "If you want to force reset, please call \n\n"
573 " ctrl->stop('all') \n\n"
574 "before you continue";
578 auto configData = MPListConfig::FromAron(dto);
585 for (
const auto&
mp : configData.mpList)
587 if (rnsMap.find(
mp.nodeSetName) == rnsMap.end())
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";
599 ARMARX_INFO <<
"-- successfully updated MP config.";
605 const std::map<std::string, VirtualRobot::RobotNodeSetPtr>& rnsMap,
606 const std::shared_ptr<common::coordination::Coordination>& coordinator)
608 const std::scoped_lock lock(
mtx_mps);
612 "If you want to force reset, please call \n\n"
613 " ctrl->stop('all') \n\n"
614 "before you continue";
618 auto configData = MPListConfig::FromAron(dto);
627 if (not coordinator->isInitialized())
633 for (
const auto& nodeSetName : coordinator->getNodesetList())
635 if (rnsMap.find(nodeSetName) == rnsMap.end())
638 <<
"Requested RobotNodeSet " << nodeSetName
639 <<
" by coordinator does not exist in the controller. MP won't be created!";
646 for (
const auto&
mp : configData.mpList)
648 if (rnsMap.find(
mp.nodeSetName) == rnsMap.end())
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";
661 ARMARX_INFO <<
"-- successfully updated MP config.";
667 const std::map<std::string, MPReInitData>&
data)
669 const std::scoped_lock lock(
mtx_mps);
673 "If you want to force reset, please call \n\n"
674 " ctrl->stop('all') \n\n"
675 "before you continue";
679 auto configData = MPListConfig::FromAron(dto);
686 for (
const auto&
mp : configData.mpList)
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";
700 ARMARX_INFO <<
"-- successfully updated MP config.";
713 ARMARX_INFO <<
"-- reconfigure MP: reinitialize the mp input output, as well as the rt "
714 "related buffer values";
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")
725 <<
"the task space pos must have 7 dimensions, got " << d.pos.size();
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();
736 else if (role ==
"nullspace" or role ==
"hand")
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;
761 const std::map<std::string, VirtualRobot::RobotNodeSetPtr>& rnsMap)
763 ARMARX_INFO <<
"-- reconfigure MP: reinitialize the mp input output, as well as the rt "
764 "related buffer values";
770 const VirtualRobot::RobotNodeSetPtr& rns = rnsMap.at(
mp.second.mp->getNodeSetName());
772 if (
mp.second.mp->getRole() ==
"taskspace")
774 Eigen::Matrix4f currentPose = rns->getTCP()->getPoseInRootFrame();
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();
782 else if (
mp.second.mp->getRole() ==
"nullspace")
785 <<
mp.second.mp->getMPName() <<
" with " << rns->getJointValues().size()
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());
796 else if (
mp.second.mp->getRole() ==
"hand")
799 <<
mp.second.mp->getMPName() <<
" with " << rns->getJointValues().size()
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());
816 const std::map<std::string, VirtualRobot::RobotNodeSetPtr>& rnsMap,
817 const std::shared_ptr<common::coordination::Coordination>& coordinator)
819 ARMARX_INFO <<
"-- reconfigure MP: reinitialize the mp input output, as well as the rt "
820 "related buffer values";
824 const auto& role =
mp.second.mp->getRole();
828 if (role ==
"taskspace")
830 const VirtualRobot::RobotNodeSetPtr& rns =
831 rnsMap.at(
mp.second.mp->getNodeSetName());
832 const Eigen::Matrix4f currentPose = rns->getTCP()->getPoseInRootFrame();
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();
840 else if (role ==
"object")
843 <<
"When MP role is object, the coordinator must be active";
845 <<
"The coordinator must first be initialized.";
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;
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();
857 else if (role ==
"nullspace" or role ==
"hand")
859 const VirtualRobot::RobotNodeSetPtr& rns =
860 rnsMap.at(
mp.second.mp->getNodeSetName());
862 <<
mp.second.mp->getMPName() <<
" with " << rns->getJointValues().size()
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());
bool resetMPs(const ::armarx::aron::data::dto::DictPtr &dto, const std::map< std::string, VirtualRobot::RobotNodeSetPtr > &rnsMap)
bool resetMPsV2(const ::armarx::aron::data::dto::DictPtr &dto, const std::map< std::string, MPReInitData > &data)
void learnFromTrajs(const ::armarx::aron::data::dto::DictPtr &dict, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
void setGoal(const DVec &goals, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
void resume(const std::string &mpName="all", const Ice::Current &iceCurrent=Ice::emptyCurrent) override
void reconfigureMPs(const MPListConfig &mpListConfig)
std::atomic_bool mpTaskRunning
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)
std::recursive_mutex mtx_mps
Ice::Double getCanVal(const std::string &mpName, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
bool isFinished(const std::string &mpName="all", const Ice::Current &iceCurrent=Ice::emptyCurrent) override
void updateMPConfig(const ::armarx::aron::data::dto::DictPtr &dto, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
void learnFromCSV(const Ice::StringSeq &fileNames=std::vector< std::string >(), const Ice::Current &iceCurrent=Ice::emptyCurrent) override
setting
void createMPs(const MPListConfig &mpListConfig)
void setStartAndGoal(const DVec &starts, const DVec &goals, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
DVec deserialize(const std::string &, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
void stop(const std::string &mpName="all", const Ice::Current &iceCurrent=Ice::emptyCurrent) override
std::map< std::string, MPInputOutput > mps
void reInitMPInputOutputData(const std::map< std::string, VirtualRobot::RobotNodeSetPtr > &rnsMap)
MPListConfig mpConfig
this variable is only needed when constructing the MP instances, therefore you don't need to use trip...
void reInitMPInputOutputDataV2(const std::map< std::string, MPReInitData > &data)
void requestStop(const std::string &mpName="all", const Ice::Current &iceCurrent=Ice::emptyCurrent) override
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
std::map< arondto::MPGroup, PhaseStopResult > phaseStops_
void setViaPoint(Ice::Double u, const DVec &viapoint, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
void reset(const std::string &mpName="all", const Ice::Current &iceCurrent=Ice::emptyCurrent) override
void reInitMPInputOutputDataV1(const std::map< std::string, VirtualRobot::RobotNodeSetPtr > &rnsMap, const std::shared_ptr< common::coordination::Coordination > &coordinator)
std::atomic< bool > isMPReady
void set(const ::armarx::StringDoubleSeqMap &, const ::armarx::StringDoubleSeqMap &, const ::armarx::StringDoubleMap &, const ::Ice::Current &iceCurrent=::Ice::emptyCurrent) override
void pause(const std::string &mpName="all", const Ice::Current &iceCurrent=Ice::emptyCurrent) override
#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.
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
armarx::aron::data::dto::Dict getMPConfig()
string serialize()
serialze
::IceInternal::Handle< Dict > DictPtr
This file is part of ArmarX.
std::shared_ptr< TSMPOutput > TSMPOutputPtr
std::shared_ptr< KeypointsMPInput > KeypointsMPInputPtr
std::shared_ptr< TSMPInput > TSMPInputPtr
std::shared_ptr< JSMPOutput > JSMPOutputPtr
std::shared_ptr< KeypointsMPOutput > KeypointsMPOutputPtr
std::shared_ptr< TSMP > TSMPPtr
std::shared_ptr< JSMP > JSMPPtr
std::shared_ptr< JSMPInput > JSMPInputPtr
std::shared_ptr< KeypointsMP > KeypointsMPPtr
Eigen::Matrix4f vec7fToMat4f(const Eigen::VectorXf &vec)