30 #include <VirtualRobot/Import/RobotImporterFactory.h>
31 #include <VirtualRobot/KinematicChain.h>
32 #include <VirtualRobot/MathTools.h>
33 #include <VirtualRobot/Nodes/RobotNode.h>
34 #include <VirtualRobot/Robot.h>
35 #include <VirtualRobot/RuntimeEnvironment.h>
37 #include <RobotAPI/interface/core/RobotState.h>
48 usingProxy(getProperty<std::string>(
"LongtermMemoryName").getValue());
49 usingProxy(getProperty<std::string>(
"RobotStateComponentName").getValue());
55 this->longtermMemoryPrx = getProxy<memoryx::LongtermMemoryInterfacePrx>(
56 getProperty<std::string>(
"LongtermMemoryName").getValue());
57 this->robotStateComponentPrx = getProxy<armarx::RobotStateComponentInterfacePrx>(
58 getProperty<std::string>(
"RobotStateComponentName").getValue());
86 Eigen::Map<const memoryx::KBM::Vector>
88 const std::vector<memoryx::KBM::Real>& position)
90 VR_ASSERT_MESSAGE((
int)(position.size()) == kbm.
getNDim(),
91 "position size doesn't match KBM dimensions");
92 return Eigen::Map<const memoryx::KBM::Vector>(position.data(), kbm.
getNDim());
95 Eigen::Map<const memoryx::KBM::Vector>
97 const std::vector<memoryx::KBM::Real>& proprioception)
99 VR_ASSERT_MESSAGE((
int)(proprioception.size()) == kbm.
getNDoF(),
100 "proprioception size doesn't match KBM DoF");
101 return Eigen::Map<const memoryx::KBM::Vector>(proprioception.data(), kbm.
getNDoF());
104 Eigen::Map<const memoryx::KBM::Matrix>
106 const std::vector<memoryx::KBM::Real>& position)
110 if (position.size() % nDim != 0)
118 Eigen::Map<const memoryx::KBM::Matrix>
120 const std::vector<memoryx::KBM::Real>& proprioception)
124 if (proprioception.size() % nDoF != 0)
132 Eigen::Map<const memoryx::KBM::Matrix>
135 if (
data.size() % rows != 0)
140 VR_ASSERT(
data.size() % rows == 0);
141 int cols =
data.size() / rows;
142 return Eigen::Map<const memoryx::KBM::Matrix>(
data.data(), rows, cols);
148 auto it = kbms.find(name);
150 if (it == kbms.end())
152 ARMARX_WARNING <<
"a KBM with the name '" << name <<
"' does not exist";
172 const Ice::Current&
c)
177 if (kbms.find(name) != kbms.end())
179 ARMARX_ERROR <<
"a KBM with the name '" << name <<
"' already exists";
188 createdFromVirtualRobot[name] =
false;
189 ARMARX_INFO <<
"created a KBM with the name '" << name <<
"'";
194 const Ice::StringSeq& robotNodeNames,
195 const std::vector<memoryx::KBM::Real>& jointValueAverages,
196 const std::vector<memoryx::KBM::Real>& spreadAnglesSequence,
197 const std::string& tcpName,
199 const Ice::Current&
c)
204 if (robotNodeNames.size() != 7)
206 ARMARX_WARNING <<
"createArmar3KBM should only be used with all 7 joints";
209 if (jointValueAverages.size() != robotNodeNames.size())
211 ARMARX_INFO <<
"robotNodeNames: " << robotNodeNames.size();
212 ARMARX_INFO <<
"jointValueAverages: " << jointValueAverages.size();
213 ARMARX_ERROR <<
"jointValueAverages should have the same size as robotNodeNames";
216 if (spreadAnglesSequence.size() != robotNodeNames.size())
218 ARMARX_INFO <<
"robotNodeNames: " << robotNodeNames.size();
219 ARMARX_INFO <<
"spreadAngles: " << spreadAnglesSequence.size();
220 ARMARX_ERROR <<
"spreadAnglesSequence should have the same size as robotNodeNames";
226 if (kbms.find(name) != kbms.end())
228 ARMARX_ERROR <<
"a KBM with the name '" << name <<
"' already exists";
235 Eigen::Map<const memoryx::KBM::Vector> spreadAngles(spreadAnglesSequence.data(),
236 spreadAnglesSequence.size());
242 std::time_t now = std::time(0);
243 std::tm* date = std::localtime(&now);
244 char when[256] = {0};
245 std::strftime(when,
sizeof(when),
"%Y-%m-%d-%H-%M-%S", date);
246 std::string baseFilename =
"data/evaluation/" + std::string(when) +
"-" + name;
248 std::ofstream metaFile(baseFilename +
"-create.txt", std::ios_base::app);
249 Eigen::Map<const memoryx::KBM::Vector> _jointValueAverages(jointValueAverages.data(),
250 jointValueAverages.size());
252 if (metaFile.is_open())
254 metaFile <<
"kbm name: " << name << std::endl;
255 metaFile <<
"joint offsets: " << _jointValueAverages << std::endl;
256 metaFile <<
"spread angles: " << spreadAngles << std::endl;
264 VirtualRobot::RobotImporterFactoryPtr importer =
265 VirtualRobot::RobotImporterFactory::fromFileExtension(
"xml", NULL);
266 std::string
filename(
"robots/ArmarIII/ArmarIII.xml");
267 VirtualRobot::RuntimeEnvironment::getDataFileAbsolute(
filename);
269 importer->loadFromFile(
filename, VirtualRobot::RobotIO::eStructure);
273 ARMARX_ERROR <<
"the ArmarIII.xml file could not be loaded";
282 VirtualRobot::RobotNodeSetPtr nodeSet = VirtualRobot::RobotNodeSet::createRobotNodeSet(
283 robot,
"ToolUseRightArm", robotNodeNames,
"Right Arm Base", tcpName,
true);
295 VirtualRobot::KinematicChainPtr chain;
297 chain.reset(
new VirtualRobot::KinematicChain(
"ToolUseRightArmChain",
299 nodeSet->getAllRobotNodes(),
300 robot->getRobotNode(tcpName)));
314 << chain->getTCP()->getGlobalPose();
316 Ice::FloatSeq jointValues;
318 for (
auto&
value : jointValueAverages)
320 jointValues.push_back(
value);
323 chain->setJointValues(jointValues);
325 <<
" is at: " << chain->getNode(0)->getJointValue();
327 << chain->getTCP()->getGlobalPose();
329 VirtualRobot::RobotNodePtr FoR = chain->getKinematicRoot();
337 << FoR->getGlobalPose();
339 unsigned int nDoF = chain->getSize();
340 ARMARX_IMPORTANT <<
"degrees of freedom of the VirtualRobot's kinematic chain: " << nDoF;
346 chain, FoR, spreadAngles, useOrientation));
348 createdFromVirtualRobot[name] =
true;
349 ARMARX_INFO <<
"created a KBM with the name '" << name <<
"'";
354 const std::vector<memoryx::KBM::Real>& proprioceptionSequence,
355 const std::vector<memoryx::KBM::Real>& positionSequence,
358 const Ice::Current&
c)
370 if (createdFromVirtualRobot[name])
373 <<
" was created from a VirtualRobot, it does not support batch learning";
380 Eigen::Map<const memoryx::KBM::Matrix> proprioception =
382 Eigen::Map<const memoryx::KBM::Matrix> position =
mapPositions(*kbm, positionSequence);
384 if (proprioception.cols() != position.cols())
386 ARMARX_ERROR <<
"proprioception and position contain different number of samples";
399 const std::vector<memoryx::KBM::Real>& proprioceptionSequence,
400 const std::vector<memoryx::KBM::Real>& positionSequence,
402 const Ice::Current&
c)
414 Eigen::Map<const memoryx::KBM::Matrix> proprioception =
416 Eigen::Map<const memoryx::KBM::Matrix> position =
mapPositions(*kbm, positionSequence);
418 if (proprioception.cols() != position.cols())
420 ARMARX_ERROR <<
"proprioception and position contain different number of samples";
424 if (createdFromVirtualRobot[name])
430 <<
"reversing proprioception order because KBM was created from VirtualRobot";
431 kbm->online(proprioception.colwise().reverse(), position, learningRate);
437 kbm->online(proprioception, position, learningRate);
443 const std::string& name,
444 const std::vector<memoryx::KBM::Real>& proprioceptionSequence,
445 const std::vector<memoryx::KBM::Real>& positionSequence,
447 const std::vector<memoryx::KBM::Real>& evaluationProprioceptionSequence,
448 const std::vector<memoryx::KBM::Real>& evaluationPositionSequence,
449 const Ice::Current&
c)
461 Eigen::Map<const memoryx::KBM::Matrix> _proprioception =
463 Eigen::Map<const memoryx::KBM::Matrix> position =
mapPositions(*kbm, positionSequence);
465 Eigen::Map<const memoryx::KBM::Matrix> _evaluationProprioception =
467 Eigen::Map<const memoryx::KBM::Matrix> evaluationPosition =
470 if (_proprioception.cols() != position.cols())
472 ARMARX_ERROR <<
"proprioception and position contain different number of samples";
476 if (_evaluationProprioception.cols() != evaluationPosition.cols())
478 ARMARX_ERROR <<
"evaluation proprioception and evaluation position contain different "
486 if (createdFromVirtualRobot[name])
492 <<
"reversing proprioception order because KBM was created from VirtualRobot";
493 proprioception = _proprioception.colwise().reverse();
494 evaluationProprioception = _evaluationProprioception.colwise().reverse();
498 proprioception = _proprioception;
499 evaluationProprioception = _evaluationProprioception;
503 ARMARX_IMPORTANT <<
"evaluation samples: " << evaluationProprioception.cols();
509 std::time_t now = std::time(0);
510 std::tm* date = std::localtime(&now);
511 char when[256] = {0};
512 std::strftime(when,
sizeof(when),
"%Y-%m-%d-%H-%M-%S", date);
513 std::string baseFilename =
"data/evaluation/" + std::string(when) +
"-" + name;
515 std::ofstream metaFile(baseFilename +
"-meta.txt", std::ios_base::app);
516 std::string evaluationFilename(baseFilename +
"-evaluation.txt");
517 std::ofstream evaluationFile(evaluationFilename, std::ios_base::app);
518 std::string trainingProprioceptionsFilename(baseFilename +
"-training-proprioceptions.txt");
519 std::ofstream trainingProprioceptionsFile(trainingProprioceptionsFilename,
521 std::string trainingPositionsFilename(baseFilename +
"-training-positions.txt");
522 std::ofstream trainingPositionsFile(trainingPositionsFilename, std::ios_base::app);
523 std::string testProprioceptionsFilename(baseFilename +
"-test-proprioceptions.txt");
524 std::ofstream testProprioceptionsFile(testProprioceptionsFilename, std::ios_base::app);
525 std::string testPositionsFilename(baseFilename +
"-test-positions.txt");
526 std::ofstream testPositionsFile(testPositionsFilename, std::ios_base::app);
528 if (metaFile.is_open())
530 metaFile <<
"kbm name: " << name << std::endl;
531 metaFile <<
"learning rate: " << learningRate << std::endl;
532 metaFile <<
"degress of freedom: " << kbm->getNDoF() << std::endl;
533 metaFile <<
"dimensions: " << kbm->getNDim() << std::endl;
534 metaFile <<
"training samples: " << proprioception.cols() << std::endl;
535 metaFile <<
"test samples: " << evaluationProprioception.cols() << std::endl;
536 metaFile <<
"evaluation columns: mean, std, median, iqr, max" << std::endl;
541 if (!trainingProprioceptionsFile.is_open())
543 ARMARX_ERROR <<
"file " << trainingProprioceptionsFilename
544 <<
" could not be opened / created";
547 if (!trainingPositionsFile.is_open())
550 <<
" could not be opened / created";
553 if (!testProprioceptionsFile.is_open())
556 <<
" could not be opened / created";
559 if (!testPositionsFile.is_open())
561 ARMARX_ERROR <<
"file " << testPositionsFilename <<
" could not be opened / created";
564 trainingProprioceptionsFile << proprioception.transpose() << std::endl;
565 trainingPositionsFile << position.transpose() << std::endl;
566 testProprioceptionsFile << evaluationProprioception.transpose() << std::endl;
567 testPositionsFile << evaluationPosition.transpose() << std::endl;
569 trainingProprioceptionsFile.close();
570 trainingPositionsFile.close();
571 testProprioceptionsFile.close();
572 testPositionsFile.close();
577 if (!evaluationFile.is_open())
579 ARMARX_ERROR <<
"file " << evaluationFilename <<
" could not be opened / created";
583 kbm->getErrors(evaluationProprioception, evaluationPosition);
585 evaluationFile << errors.
Mean <<
", " << errors.STD <<
", " << errors.Median <<
", "
586 << errors.IQR <<
", " << errors.Max << std::endl;
588 for (
int i = 0; i < proprioception.cols(); i++)
590 kbm->online(proprioception.col(i), position.col(i), learningRate);
594 errors = kbm->getErrors(evaluationProprioception, evaluationPosition);
595 ARMARX_IMPORTANT <<
"online learning error after step " << (i + 1) <<
": " << errors;
596 evaluationFile << errors.Mean <<
", " << errors.STD <<
", " << errors.Median <<
", "
597 << errors.IQR <<
", " << errors.Max << std::endl;
600 evaluationFile.close();
603 std::vector<memoryx::KBM::Real>
605 const std::vector<memoryx::KBM::Real>& proprioceptionSequence,
606 const Ice::Current&
c)
612 return std::vector<memoryx::KBM::Real>();
615 Eigen::Map<const memoryx::KBM::Matrix> proprioception =
618 int nDim = kbm->getNDim();
619 int nSamples = proprioception.cols();
620 std::vector<memoryx::KBM::Real> predictionSequence(nDim * nSamples);
621 Eigen::Map<memoryx::KBM::Matrix> prediction(predictionSequence.data(), nDim, nSamples);
623 if (createdFromVirtualRobot[name])
628 prediction = kbm->predict(proprioception.colwise().reverse());
632 prediction = kbm->predict(proprioception);
635 ARMARX_INFO <<
"KBM '" << name <<
"' predicted: " << prediction.transpose();
636 return predictionSequence;
641 const std::vector<memoryx::KBM::Real>& proprioceptionSequence,
642 const std::vector<memoryx::KBM::Real>& positionSequence,
643 const Ice::Current&
c)
655 Eigen::Map<const memoryx::KBM::Matrix> proprioception =
657 Eigen::Map<const memoryx::KBM::Matrix> position =
mapPositions(*kbm, positionSequence);
659 if (proprioception.cols() != position.cols())
661 ARMARX_ERROR <<
"proprioception and position contain different number of samples";
669 if (createdFromVirtualRobot[name])
674 errors = kbm->getErrors(proprioception.colwise().reverse(), position);
678 errors = kbm->getErrors(proprioception, position);
687 Eigen::Map<const memoryx::KBM::Matrix> proprioception =
688 mapMatrix(nDoF, proprioceptionAccumulator);
689 Eigen::Map<const memoryx::KBM::Matrix> position =
mapMatrix(nDim, positionAccumulator);
691 ARMARX_VERBOSE <<
"proprioception samples: " << proprioception.cols();
695 << proprioception.rowwise().minCoeff().transpose();
697 << proprioception.rowwise().maxCoeff().transpose();
698 ARMARX_VERBOSE <<
"proprioception average: " << proprioception.rowwise().mean().transpose();
699 ARMARX_VERBOSE <<
"position minima: " << position.rowwise().minCoeff().transpose();
700 ARMARX_VERBOSE <<
"position maxima: " << position.rowwise().maxCoeff().transpose();
701 ARMARX_VERBOSE <<
"position average: " << position.rowwise().mean().transpose();
707 Eigen::Map<const memoryx::KBM::Matrix> rawJointValues =
708 mapMatrix(nDoF, rawJointValuesAccumulator);
710 ARMARX_VERBOSE <<
"raw jointValue samples: " << rawJointValues.cols();
712 std::vector<memoryx::KBM::Real> result(nDoF);
713 Eigen::Map<memoryx::KBM::Vector> averages(result.data(), nDoF);
714 averages = rawJointValues.rowwise().mean();
716 Ice::DoubleSeq resultFloat(result.begin(), result.end());
723 Eigen::Map<const memoryx::KBM::Matrix> proprioceptions =
724 mapMatrix(nDoF, proprioceptionAccumulator);
726 ARMARX_VERBOSE <<
"proprioception samples: " << proprioceptions.cols();
728 std::vector<memoryx::KBM::Real> result(nDoF);
729 Eigen::Map<memoryx::KBM::Vector> spreadAngles(result.data(), nDoF);
736 for (
int i = 0; i < nDoF; i++)
738 spreadAngles[i] = fmin(fabs(leftSpreadAngles[i]), fabs(rightSpreadAngles[i]));
743 Ice::DoubleSeq resultFloat(result.begin(), result.end());
749 const std::vector<memoryx::KBM::Real>& rawJointValuesAverages,
750 const Ice::Current&
c)
752 if (proprioceptionAccumulator.size() != 0)
754 ARMARX_ERROR <<
"proprioception accumulator should be empty, when using setting it "
755 "from raw joint accumulator";
758 if (rawJointValuesAccumulator.size() % rawJointValuesAverages.size() != 0)
760 ARMARX_ERROR <<
"rawJointValuesAverages size is incompatible to accumulator size";
763 ARMARX_INFO <<
"rawJointValuesAccumualtor: " << rawJointValuesAccumulator;
764 std::vector<memoryx::KBM::Real> proprioceptionsFromRawJointAccumulator;
767 for (
auto jointValue : rawJointValuesAccumulator)
769 if (i == rawJointValuesAverages.size())
774 float offset = rawJointValuesAverages[i];
780 proprioceptionsFromRawJointAccumulator.push_back(jointValue - offset);
783 ARMARX_INFO <<
"proprioceptionsFromRawJointAccumulator: "
784 << proprioceptionsFromRawJointAccumulator;
785 proprioceptionAccumulator = proprioceptionsFromRawJointAccumulator;
795 Eigen::Map<const memoryx::KBM::Matrix> positions =
mapMatrix(nDim, positionAccumulator);
796 minima = positions.rowwise().minCoeff();
797 maxima = positions.rowwise().maxCoeff();
805 const Ice::Current&
c)
807 online(name, proprioceptionAccumulator, positionAccumulator, learningRate,
c);
813 const Ice::Current&
c)
816 proprioceptionAccumulator,
819 evaluationProprioceptionAccumulator,
820 evaluationPositionAccumulator,
828 const Ice::Current&
c)
830 batch(name, proprioceptionAccumulator, positionAccumulator, method, threshold,
c);
836 printErrors(name, proprioceptionAccumulator, positionAccumulator,
c);
842 predict(name, proprioceptionAccumulator,
c);
855 const Ice::Current&
c)
860 positionAccumulator.insert(positionAccumulator.end(), position.begin(), position.end());
867 const Ice::Current&
c)
872 proprioceptionAccumulator.insert(
873 proprioceptionAccumulator.end(), proprioception.begin(), proprioception.end());
880 const std::vector<memoryx::KBM::Real>& rawJointValuesSequence,
881 const Ice::Current&
c)
886 rawJointValuesAccumulator.insert(rawJointValuesAccumulator.end(),
887 rawJointValuesSequence.begin(),
888 rawJointValuesSequence.end());
895 const Ice::Current&
c)
900 evaluationPositionAccumulator.insert(
901 evaluationPositionAccumulator.end(), position.begin(), position.end());
908 const std::vector<memoryx::KBM::Real>& proprioception,
909 const Ice::Current&
c)
914 evaluationProprioceptionAccumulator.insert(evaluationProprioceptionAccumulator.end(),
915 proprioception.begin(),
916 proprioception.end());
921 std::vector<memoryx::KBM::Real>
923 const std::vector<memoryx::KBM::Real>& targetPosition,
924 const Ice::Current&
c)
934 return std::vector<memoryx::KBM::Real>();
937 Eigen::Map<const memoryx::KBM::Vector>
target(
mapPosition(*kbm, targetPosition));
942 std::vector<memoryx::KBM::Real> result(kbm->getNDoF());
943 Eigen::Map<memoryx::KBM::Vector> solution(result.data(), kbm->getNDoF());
952 for (
unsigned int i = 0; i < solutions.size(); ++i)
959 if (createdFromVirtualRobot[name])
961 ARMARX_ERROR <<
"solveGlobalIK does not yet support KBMs created from Virtual Robot!";
967 std::vector<memoryx::KBM::Real>
969 const std::string& name,
970 const std::vector<memoryx::KBM::Real>& targetPosition,
971 const std::vector<memoryx::KBM::Real>& currentPosition,
972 const std::vector<memoryx::KBM::Real>& currentProprioception,
973 const std::vector<memoryx::KBM::Real>& lowerProprioceptionLimitsSequence,
974 const std::vector<memoryx::KBM::Real>& upperProprioceptionLimitsSequence,
975 const Ice::Current&
c)
985 return std::vector<memoryx::KBM::Real>();
988 Eigen::Map<const memoryx::KBM::Vector>
target(
mapPosition(*kbm, targetPosition));
989 Eigen::Map<const memoryx::KBM::Vector> current(
mapPosition(*kbm, currentPosition));
990 Eigen::Map<const memoryx::KBM::Vector> proprioception(
992 Eigen::Map<const memoryx::KBM::Vector> lowerProprioceptionLimits(
994 Eigen::Map<const memoryx::KBM::Vector> upperProprioceptionLimits(
1000 if (minima.size() !=
target.size())
1002 ARMARX_ERROR <<
"minima and target have different size";
1003 return std::vector<memoryx::KBM::Real>();
1006 if (maxima.size() !=
target.size())
1009 ARMARX_ERROR <<
"maxima and target have different size";
1010 return std::vector<memoryx::KBM::Real>();
1013 for (
int i = 0; i < kbm->getNDim(); i++)
1015 if (
target[i] < minima[i] - 90)
1019 return std::vector<memoryx::KBM::Real>();
1022 if (
target[i] > maxima[i] + 90)
1026 return std::vector<memoryx::KBM::Real>();
1033 std::vector<memoryx::KBM::Real> result(kbm->getNDoF());
1034 Eigen::Map<memoryx::KBM::Vector> solution(result.data(), kbm->getNDoF());
1041 if (createdFromVirtualRobot[name])
1046 ARMARX_IMPORTANT <<
"reversing proprioception and limits order because KBM was created "
1047 "from VirtualRobot";
1051 proprioception.reverse(),
1052 lowerProprioceptionLimits.reverse(),
1053 upperProprioceptionLimits.reverse(),
1062 lowerProprioceptionLimits,
1063 upperProprioceptionLimits,
1067 if (createdFromVirtualRobot[name])
1073 solution = solution.colwise().reverse();
1098 return LO +
static_cast<float>(rand()) / (
static_cast<float>(RAND_MAX / (HI - LO)));
1106 float stepSizeFactor,
1115 if (positionDeltas.norm() > maxStepSize)
1117 positionDeltas *= maxStepSize / positionDeltas.norm();
1129 #ifdef KBM_USE_DOUBLE_PRECISION
1146 if (lowerProprioceptionLimits.size() != upperProprioceptionLimits.size())
1151 int n = lowerProprioceptionLimits.size();
1154 for (
int i = 0; i < n; i++)
1156 float l = lowerProprioceptionLimits(i);
1157 float u = upperProprioceptionLimits(i);
1173 int n = solution.size();
1175 if (lowerProprioceptionLimits.size() != n)
1177 ARMARX_ERROR_S <<
"lower proprioception limits have wrong length: "
1178 << lowerProprioceptionLimits.size() <<
", should be " << n;
1181 if (upperProprioceptionLimits.size() != n)
1183 ARMARX_ERROR_S <<
"upper proprioception limits have wrong length: "
1184 << upperProprioceptionLimits.size() <<
", should be " << n;
1190 for (
int i = 0; i < n; i++)
1192 if ((solution(i) < lowerProprioceptionLimits(i)) ||
1193 (solution(i) > upperProprioceptionLimits(i)))
1204 Eigen::Map<memoryx::KBM::Vector>& solution,
1211 int n = solution.size();
1213 if (lowerProprioceptionLimits.size() != n)
1215 ARMARX_ERROR_S <<
"lower proprioception limits have wrong length: "
1216 << lowerProprioceptionLimits.size() <<
", should be " << n;
1219 if (upperProprioceptionLimits.size() != n)
1221 ARMARX_ERROR_S <<
"upper proprioception limits have wrong length: "
1222 << upperProprioceptionLimits.size() <<
", should be " << n;
1228 bool inLimits =
true;
1230 for (
int i = 0; i < n; i++)
1232 if (solution(i) < lowerProprioceptionLimits(i))
1234 solution(i) = lowerProprioceptionLimits(i);
1238 if (solution(i) > upperProprioceptionLimits(i))
1240 solution(i) = upperProprioceptionLimits(i);
1255 Eigen::Map<memoryx::KBM::Vector>& solution,
1258 float positionTolerance,
1260 bool requireImprovment,
1262 float stepSizeFactor,
1266 float bestDistance = FLT_MAX;
1267 bool inLimits =
false;
1269 std::vector<memoryx::KBM::Real> newSolutionSequence(kbm.
getNDoF());
1270 Eigen::Map<memoryx::KBM::Vector> newSolution(newSolutionSequence.data(), kbm.
getNDoF());
1272 for (
int i = 0; i < maxSolves; i++)
1278 startProprioception = currentProprioception;
1282 startProprioception =
1287 <<
" proprioception: " << startProprioception.transpose();
1297 startProprioception,
1319 float distance = (targetPosition - testPosition).
norm();
1327 newSolution, lowerProprioceptionLimits, upperProprioceptionLimits);
1333 <<
"solution was not within limits, but enforced limits so now it is";
1339 testPosition = kbm.
predict(newSolution);
1349 newSolution, lowerProprioceptionLimits, upperProprioceptionLimits);
1352 if (applyLimits && !currentInLimits)
1356 ARMARX_ERROR_S <<
"lower proprioception limits: " << lowerProprioceptionLimits;
1357 ARMARX_ERROR_S <<
"upper proprioception limits: " << upperProprioceptionLimits;
1360 if (inLimits && !currentInLimits)
1363 <<
"ignoring solution because we already found one that is within the limits";
1368 float distance = (targetPosition - newPosition).
norm();
1373 if ((
distance < bestDistance) || (currentInLimits && !inLimits))
1376 inLimits = currentInLimits;
1377 solution = newSolution;
1380 if (inLimits && (bestDistance < positionTolerance))
1389 ARMARX_IMPORTANT_S <<
"final distance: " << bestDistance <<
", in limits: " << inLimits;
1391 if (bestDistance < positionTolerance)
1406 Eigen::Map<memoryx::KBM::Vector>& solution,
1407 float positionTolerance,
1409 bool requireImprovment,
1411 float stepSizeFactor,
1415 assert(targetPosition.size() == kbm.
getNDim());
1416 assert(currentPosition.size() == kbm.
getNDim());
1417 assert(currentProprioception.size() == kbm.
getNDoF());
1418 assert(solution.size() == kbm.
getNDoF());
1423 solution = currentProprioception;
1428 float bestDistance = (targetPosition - currentPosition).
norm();
1433 if (bestDistance <= positionTolerance)
1453 for (
int step = 0; step < maxSteps; ++step)
1461 simulatedProprioception,
1468 simulatedProprioception +=
deltas;
1473 predictedPosition = kbm.
predict(simulatedProprioception);
1479 float distance = (targetPosition - predictedPosition).
norm();
1484 solution = simulatedProprioception;
1491 if (requireImprovment && (
distance >= bestDistance))
1502 solution = simulatedProprioception;
1509 if (
deltas.norm() < minimumDelta)
1521 std::vector<std::string> kbmKeys;
1523 for (
auto it : kbms)
1525 kbmKeys.push_back(it.first);
1534 positionAccumulator.clear();
1535 proprioceptionAccumulator.clear();
1536 rawJointValuesAccumulator.clear();
1541 const std::string& nodeSetName,
1542 const std::string& referenceFrameName,
1543 const std::string& robotName,
1544 const Ice::Current&
c)
1550 auto kbmSeg = this->longtermMemoryPrx->getKBMSegment();
1559 kbmSeg->addEntity(kbmData);
1564 ARMARX_WARNING <<
"Could not store KBM! No KBM segment in longterm memory!";
1572 const std::string& nodeSetName,
1573 const std::string& referenceFrameName,
1574 const std::string& robotName,
1575 const Ice::Current&
c)
1578 auto kbmSeg = this->longtermMemoryPrx->getKBMSegment();
1579 std::string kbmEntityName = robotName +
"_" + referenceFrameName +
"_" + nodeSetName;
1581 if (kbmSeg && kbmSeg->hasEntityByName(kbmEntityName))
1583 auto entity = kbmSeg->getEntityByName(kbmEntityName);
1590 int nDoF = robot->getRobotNodeSet(nodeSetName)->getSize();
1593 armarx::MatrixVariantPtr::dynamicCast(kbmData->getControlNet());
1598 Eigen::VectorXd::Zero(nDoF),
1599 Eigen::VectorXd::Constant(nDoF,
M_PI / 4.0f),
1600 controlNet->toEigen().cast<
double>());
1601 createdFromVirtualRobot[kbmName] =
1606 ARMARX_WARNING <<
"Could not restore KBM entity specified by: " << kbmEntityName;
1615 const std::string& referenceFrameName,
1616 const std::string& robotName,
1617 const Ice::Current&
c)
1619 std::string kbmEntityName = robotName +
"_" + referenceFrameName +
"_" + nodeSetName;
1621 return (this->longtermMemoryPrx->getKBMSegment() &&
1622 this->longtermMemoryPrx->getKBMSegment()->hasEntityByName(kbmEntityName));