27 #include <VirtualRobot/LinkedCoordinate.h>
28 #include <VirtualRobot/Robot.h>
29 #include <VirtualRobot/RobotNodeSet.h>
40 MotionModelKBM::MotionModelKBM(std::string referenceNodeName,
41 std::string nodeSetName,
43 memoryx::LongtermMemoryInterfacePrx longtermMemory) :
46 this->nodeSetName = nodeSetName;
47 this->referenceNodeName = referenceNodeName;
49 this->longtermMemory = longtermMemory;
50 memoryName = robotStateProxy->getRobotName() +
"_" + referenceNodeName +
"_" + nodeSetName;
57 const armarx::LinkedPoseBasePtr& poseAtLastLocalization,
58 const armarx::PoseBasePtr& globalRobotPoseAtLastLocalization,
59 const MultivariateNormalDistributionBasePtr& uncertaintyAtLastLocalization,
60 const Ice::Current&
c)
63 this->poseAtLastLocalization = poseAtLastLocalization;
64 timeOfLastSuccessfulLocalization =
65 armarx::TimestampVariantPtr::dynamicCast(timeOfLastLocalizationStart->clone());
67 if (globalRobotPoseAtLastLocalization)
69 this->globalRobotPoseAtLastLocalization = globalRobotPoseAtLastLocalization;
72 if (uncertaintyAtLastLocalization)
74 this->uncertaintyAtLastLocalization = uncertaintyAtLastLocalization;
79 pose->changeFrame(referenceNodeName);
80 auto poseKBM = armarx::LinkedPosePtr::dynamicCast(pose->clone());
81 poseKBM->changeFrame(
robot->getRobotNodeSet(nodeSetName)->getKinematicRoot()->getName());
83 KBM::Matrix shape = poseKBM->toEigen().block<3, 1>(0, 3).cast<double>();
86 kbm->online(this->
getJointAngles(poseAtLastLocalization->referenceRobot).cast<
double>(),
95 armarx::LinkedPosePtr::dynamicCast(poseAtLastLocalization);
99 auto snapShot = robotStateProxy->getRobotSnapshot(
robot->getName());
103 auto time = IceUtil::Time::now();
104 Eigen::Vector3f kbmPos = this->
kbm->predict(jointAngles).cast<
float>();
106 << (IceUtil::Time::now() - time).toMilliSecondsDouble() <<
" ms";
107 auto nodeSet =
robot->getRobotNodeSet(nodeSetName);
110 kbmPos, nodeSet->getKinematicRoot()->getName(), linkedPose->agent);
114 << (pose.block<3, 1>(0, 3) - framedKbmPos.
toEigen()).
norm() <<
" mm";
115 pose.block<3, 1>(0, 3) = framedKbmPos.
toEigen();
126 Eigen::MatrixXf proprioception(nDoF, 1);
127 std::vector<float>
jointAngles =
robot->getRobotNodeSet(nodeSetName)->getJointValues();
129 for (
int i = 0; i < nDoF; i++)
134 return proprioception;
145 auto kbmSeg = longtermMemory->getKBMSegment();
153 auto entity = kbmSeg->getEntityByName(
memoryName);
154 KBMDataPtr kbmData = KBMDataPtr::dynamicCast(entity);
161 kbmSeg->updateEntity(kbmData->getId(), kbmData);
171 <<
" Entity ice_id:" << entity->ice_id();
182 robotStateProxy->getRobotName()));
183 ARMARX_INFO_S <<
"Adding new kbm with name " << kbmData->getName();
184 kbmSeg->addEntity(kbmData);
200 MotionModelKBM::init()
206 nDoF =
robot->getRobotNodeSet(this->nodeSetName)->getSize();
208 auto kbmSeg = longtermMemory->getKBMSegment();
212 if (kbmSeg && kbmSeg->hasEntityByName(
memoryName))
215 auto entity = kbmSeg->getEntityByName(
memoryName);
216 KBMDataPtr kbmData = KBMDataPtr::dynamicCast(entity);
222 armarx::MatrixVariantPtr::dynamicCast(kbmData->getControlNet());
227 Eigen::VectorXd::Zero(nDoF),
228 Eigen::VectorXd::Constant(nDoF,
M_PI / 4.0f),
229 controlNet->toEigen().cast<
double>());
234 <<
" Entity ice_id:" << entity->ice_id();
250 auto nodeSet =
robot->getRobotNodeSet(nodeSetName);
256 kbmSeg->addEntity(kbmData);
257 ARMARX_VERBOSE <<
"Adding new entity with name " << kbmData->getName();
260 catch (VirtualRobot::VirtualRobotException& e)
284 VirtualRobot::RobotNodeSetPtr nodeSet,
287 ARMARX_INFO_S <<
"Starting to generate KBM with random samples for nodeset "
288 << nodeSet->getName();
292 std::vector<RobotNodePtr> nodes = nodeSet->getAllRobotNodes();
293 RobotNodePtr root = nodeSet->getKinematicRoot();
294 RobotNodePtr TCP = nodeSet->getTCP();
295 size_t nJoints = nodes.size();
296 size_t nOutputDim = 3;
297 Eigen::VectorXf jointMin = Eigen::VectorXf::Zero(nJoints, 1);
298 Eigen::VectorXf jointMax = Eigen::VectorXf::Zero(nJoints, 1);
300 for (
size_t i = 0; i < nJoints; i++)
302 RobotNodePtr
n = nodes[i];
303 jointMax(i) =
n->getJointLimitHi() - 0.1f;
304 jointMin(i) =
n->getJointLimitLo() + 0.1f;
316 size_t nTrainingSamples = (size_t)pow(nOutputDim, nJoints);
318 std::vector<memoryx::KBM::Real> proprioceptionAccumulator;
319 std::vector<memoryx::KBM::Real> positionAccumulator;
321 for (
size_t i = 0; i < nTrainingSamples; i++)
323 Ice::DoubleSeq proprioception, pos;
325 CreateSample(nodeSet, jointMax, jointMin, root, TCP, proprioception, pos);
327 proprioceptionAccumulator.insert(
328 proprioceptionAccumulator.end(), proprioception.begin(), proprioception.end());
329 positionAccumulator.insert(positionAccumulator.end(), pos.begin(), pos.end());
331 auto mapVectorToMatrix = [](
const std::vector<memoryx::KBM::Real>& vec,
size_t rows)
333 size_t cols = vec.size() / rows;
334 return Eigen::Map<const memoryx::KBM::Matrix>(vec.data(), rows, cols);
337 kbm->batch(mapVectorToMatrix(proprioceptionAccumulator, nJoints),
338 mapVectorToMatrix(positionAccumulator, nOutputDim),
371 memoryx::MultivariateNormalDistributionBasePtr
374 if (uncertaintyAtLastLocalization)
376 auto handNodeName =
robot->getRobotNodeSet(nodeSetName)->getTCP()->getName();
378 poseAtLastLocalization->referenceRobot->getRobotNode(handNodeName)
379 ->getPoseInRootFrame());
381 armarx::PosePtr::dynamicCast(robotStateProxy->getSynchronizedRobot()
382 ->getRobotNode(handNodeName)
383 ->getPoseInRootFrame());
386 float dist = (oldHandNodePose->toEigen().block<3, 1>(0, 3) -
387 newHandNodePose->toEigen().block<3, 1>(0, 3))
393 MultivariateNormalDistributionPtr::dynamicCast(uncertaintyAtLastLocalization)
394 ->toEigenCovariance();
395 Eigen::Matrix3f newUncertainty = oldUncertainty + additionalUncertainty;
398 armarx::Vector3Ptr::dynamicCast(poseAtLastLocalization->position)->toEigen(),
415 Eigen::VectorXf jointMax,
416 Eigen::VectorXf jointMin,
419 Ice::DoubleSeq& prop,
420 Ice::DoubleSeq& shape)
422 unsigned int nJoints = nodeSet->getSize();
423 Eigen::VectorXf rnd = Eigen::VectorXf::Random(nJoints, 1);
424 Eigen::VectorXf sample =
425 (rnd + Eigen::VectorXf::Ones(nJoints, 1)).cwiseProduct((jointMax - jointMin) / 2) +
428 for (
size_t k = 0; k < nJoints; k++)
430 nodeSet->getNode(k)->setJointValue(sample(k));
432 std::vector<float> actualJointValues = nodeSet->getJointValues();
438 Eigen::Vector3f tcpPos = TCP->getTransformationFrom(root).block<3, 1>(0, 3);
440 for (
size_t j = 0; j < nJoints; j++)
442 prop.push_back(actualJointValues[j]);
445 assert(tcpPos.rows() >= 0);
446 for (
size_t k = 0; k < static_cast<std::size_t>(tcpPos.rows()); k++)
448 shape.push_back(tcpPos(k));