29 #include <VirtualRobot/LinkedCoordinate.h>
32 #include <VirtualRobot/RobotNodeSet.h>
33 #include <VirtualRobot/Robot.h>
39 MotionModelKBM::MotionModelKBM(std::string referenceNodeName, std::string nodeSetName,
42 this->nodeSetName = nodeSetName;
43 this->referenceNodeName = referenceNodeName;
45 this->longtermMemory = longtermMemory;
46 memoryName = robotStateProxy->getRobotName() +
"_" + referenceNodeName +
"_" + nodeSetName;
52 const MultivariateNormalDistributionBasePtr& uncertaintyAtLastLocalization,
const Ice::Current&
c)
55 this->poseAtLastLocalization = poseAtLastLocalization;
56 timeOfLastSuccessfulLocalization = armarx::TimestampVariantPtr::dynamicCast(timeOfLastLocalizationStart->clone());
58 if (globalRobotPoseAtLastLocalization)
60 this->globalRobotPoseAtLastLocalization = globalRobotPoseAtLastLocalization;
63 if (uncertaintyAtLastLocalization)
65 this->uncertaintyAtLastLocalization = uncertaintyAtLastLocalization;
70 pose->changeFrame(referenceNodeName);
71 auto poseKBM = armarx::LinkedPosePtr::dynamicCast(pose->clone());
72 poseKBM->changeFrame(
robot->getRobotNodeSet(nodeSetName)->getKinematicRoot()->getName());
74 KBM::Matrix shape = poseKBM->toEigen().block<3, 1>(0, 3).cast<double>();
77 kbm->online(this->
getJointAngles(poseAtLastLocalization->referenceRobot).cast<
double>(), shape);
88 auto snapShot = robotStateProxy->getRobotSnapshot(
robot->getName());
91 auto time = IceUtil::Time::now();
92 Eigen::Vector3f kbmPos = this->
kbm->predict(jointAngles).cast<
float>();
93 ARMARX_DEBUG_S <<
"KBM prediction Took: " << (IceUtil::Time::now() - time).toMilliSecondsDouble() <<
" ms";
94 auto nodeSet =
robot->getRobotNodeSet(nodeSetName);
99 ARMARX_DEBUG_S <<
"Difference between KBM and robot model: " << (pose.block<3, 1>(0, 3) - framedKbmPos.
toEigen()).
norm() <<
" mm";
100 pose.block<3, 1>(0, 3) = framedKbmPos.
toEigen();
111 Eigen::MatrixXf proprioception(nDoF, 1);
112 std::vector<float>
jointAngles =
robot->getRobotNodeSet(nodeSetName)->getJointValues();
114 for (
int i = 0; i < nDoF; i++)
119 return proprioception;
129 auto kbmSeg = longtermMemory->getKBMSegment();
138 auto entity = kbmSeg->getEntityByName(
memoryName);
139 KBMDataPtr kbmData = KBMDataPtr::dynamicCast(entity);
146 kbmSeg->updateEntity(kbmData->getId(), kbmData);
164 ARMARX_INFO_S <<
"Adding new kbm with name " << kbmData->getName();
165 kbmSeg->addEntity(kbmData);
181 void MotionModelKBM::init()
187 nDoF =
robot->getRobotNodeSet(this->nodeSetName)->getSize();
189 auto kbmSeg = longtermMemory->getKBMSegment();
193 if (kbmSeg && kbmSeg->hasEntityByName(
memoryName))
196 auto entity = kbmSeg->getEntityByName(
memoryName);
197 KBMDataPtr kbmData = KBMDataPtr::dynamicCast(entity);
204 this->
kbm =
KBM::Models::KBM::createKBM(nDoF, controlNet->rows, Eigen::VectorXd::Zero(nDoF), Eigen::VectorXd::Constant(nDoF,
M_PI / 4.0f), controlNet->toEigen().cast<
double>());
224 auto nodeSet =
robot->getRobotNodeSet(nodeSetName);
227 nodeSet->getKinematicRoot());
231 kbmSeg->addEntity(kbmData);
232 ARMARX_VERBOSE <<
"Adding new entity with name " << kbmData->getName();
235 catch (VirtualRobot::VirtualRobotException& e)
259 ARMARX_INFO_S <<
"Starting to generate KBM with random samples for nodeset " << nodeSet->getName();
263 std::vector<RobotNodePtr> nodes = nodeSet->getAllRobotNodes();
264 RobotNodePtr root = nodeSet->getKinematicRoot();
265 RobotNodePtr TCP = nodeSet->getTCP();
266 size_t nJoints = nodes.size();
267 size_t nOutputDim = 3;
268 Eigen::VectorXf jointMin = Eigen::VectorXf::Zero(nJoints, 1);
269 Eigen::VectorXf jointMax = Eigen::VectorXf::Zero(nJoints, 1);
271 for (
size_t i = 0; i < nJoints; i++)
273 RobotNodePtr n = nodes[i];
274 jointMax(i) = n->getJointLimitHi() - 0.1f;
275 jointMin(i) = n->getJointLimitLo() + 0.1f;
287 size_t nTrainingSamples = (size_t)pow(nOutputDim, nJoints);
289 std::vector<memoryx::KBM::Real> proprioceptionAccumulator;
290 std::vector<memoryx::KBM::Real> positionAccumulator;
292 for (
size_t i = 0; i < nTrainingSamples; i++)
294 Ice::DoubleSeq proprioception, pos;
296 CreateSample(nodeSet, jointMax, jointMin, root, TCP, proprioception, pos);
298 proprioceptionAccumulator.insert(proprioceptionAccumulator.end(), proprioception.begin(), proprioception.end());
299 positionAccumulator.insert(positionAccumulator.end(), pos.begin(), pos.end());
301 auto mapVectorToMatrix = [](
const std::vector<memoryx::KBM::Real>& vec,
size_t rows)
303 size_t cols = vec.size() / rows;
304 return Eigen::Map<const memoryx::KBM::Matrix>(vec.data(), rows, cols);
307 kbm->batch(mapVectorToMatrix(proprioceptionAccumulator, nJoints),
345 if (uncertaintyAtLastLocalization)
347 auto handNodeName =
robot->getRobotNodeSet(nodeSetName)->getTCP()->getName();
348 armarx::PosePtr oldHandNodePose = armarx::PosePtr::dynamicCast(poseAtLastLocalization->referenceRobot->getRobotNode(handNodeName)->getPoseInRootFrame());
349 armarx::PosePtr newHandNodePose = armarx::PosePtr::dynamicCast(robotStateProxy->getSynchronizedRobot()->getRobotNode(handNodeName)->getPoseInRootFrame());
352 float dist = (oldHandNodePose->toEigen().block<3, 1>(0, 3) - newHandNodePose->toEigen().block<3, 1>(0, 3)).norm();
356 Eigen::Matrix3f oldUncertainty = MultivariateNormalDistributionPtr::dynamicCast(uncertaintyAtLastLocalization)->toEigenCovariance();
357 Eigen::Matrix3f newUncertainty = oldUncertainty + additionalUncertainty;
372 void MotionModelKBM::CreateSample(RobotNodeSetPtr nodeSet, Eigen::VectorXf jointMax, Eigen::VectorXf jointMin, RobotNodePtr root, RobotNodePtr TCP, Ice::DoubleSeq& prop, Ice::DoubleSeq& shape)
374 unsigned int nJoints = nodeSet->getSize();
375 Eigen::VectorXf rnd = Eigen::VectorXf::Random(nJoints, 1);
376 Eigen::VectorXf sample = (rnd + Eigen::VectorXf::Ones(nJoints, 1)).cwiseProduct((jointMax - jointMin) / 2) + jointMin;
378 for (
size_t k = 0; k < nJoints; k++)
380 nodeSet->getNode(k)->setJointValue(sample(k));
382 std::vector<float> actualJointValues = nodeSet->getJointValues();
388 Eigen::Vector3f tcpPos = TCP->getTransformationFrom(root).block<3, 1>(0, 3);
390 for (
size_t j = 0; j < nJoints; j++)
392 prop.push_back(actualJointValues[j]);
395 assert(tcpPos.rows() >= 0);
396 for (
size_t k = 0; k < static_cast<std::size_t>(tcpPos.rows()); k++)
398 shape.push_back(tcpPos(k));