23 #include "VirtualRobot/Workspace/Reachability.h"
24 #include "MotionPlanning/CSpace/CSpaceSampled.h"
25 #include "MotionPlanning/Planner/BiRrt.h"
26 #include "MotionPlanning/Planner/Rrt.h"
27 #include "VirtualRobot/CollisionDetection/CDManager.h"
28 #include "MotionPlanning/PostProcessing/ShortcutProcessor.h"
45 this->robotProxy = robot->clone();
46 this->currentRns =
"";
49 this->IKCalibrationMap = std::map<std::string, IKCalibration>();
50 this->IKCalibrationMap.insert(std::pair<std::string, IKCalibration>(
"Armar3", IKCalibration::createIKCalibration(1000, 0.005, 500, 0.3, 100, 1.0)));
51 this->IKCalibrationMap.insert(std::pair<std::string, IKCalibration>(
"Armar4", IKCalibration::createIKCalibration(10000, 0.005, 100, 0.6, 100, 1.0)));
52 this->IKCalibrationMap.insert(std::pair<std::string, IKCalibration>(
"Armar6", IKCalibration::createIKCalibration(100, 0.5, 500, 1.1, 500, 1.1)));
53 this->IKCalibrationMap.insert(std::pair<std::string, IKCalibration>(
"Custom", IKCalibration::createIKCalibration(100, 100, 100, 100, 100, 100)));
76 KinematicSolver::IKCalibration KinematicSolver::IKCalibration::createIKCalibration(
int smallIterations,
double smallStepSize,
int mediumIterations,
double mediumStepSize,
int largeIterations,
double largeStepSize)
78 IKCalibration calibration;
79 calibration.smallIterations = smallIterations;
80 calibration.smallStepSize = smallStepSize;
81 calibration.mediumIterations = mediumIterations;
82 calibration.mediumStepSize = mediumStepSize;
83 calibration.largeIterations = largeIterations;
84 calibration.largeStepSize = largeStepSize;
100 return KinematicSolver::singleton;
117 IKCalibration calibration = calibrate();
120 RobotNodeSetPtr kcPrx = robotProxy->getRobotNodeSet(kc->getName());
121 std::vector<double> jointValues;
122 int failureCounter = 0;
127 std::vector<float> jv;
128 float rn = 1.0f / (
float)RAND_MAX;
129 for (
unsigned int i = 0; i < kcPrx->getSize(); i++)
131 RobotNodePtr ro = kcPrx->getNode(i);
132 float r = (
float)rand() * rn;
133 float v = ro->getJointLimitLo() + (ro->getJointLimitHi() - ro->getJointLimitLo()) * r;
136 robotProxy->setJointValues(kcPrx, jv);
140 GenericIKSolverPtr ikSolver = this->IKSetup(calibration.largeStepSize, calibration.largeIterations, 10.0, 0.50, kcPrx);
141 Pose targetPose =
Pose(globalPose->position, globalPose->orientation);
142 std::vector<float> output = ikSolver->solveNoRNSUpdate(targetPose.
toEigen(), selection);
143 jointValues = std::vector<double>(output.begin(), output.end());
146 while (jointValues.size() == 0 && failureCounter <= iterations);
153 PoseBasePtr globalPose = PoseBasePtr(
new Pose(kc->getKinematicRoot()->toGlobalCoordinateSystem(localPose->toEigen())));
154 return this->solveIK(kc, globalPose, selection, 50);
160 IKCalibration calibration = calibrate();
162 RobotNodeSetPtr kcPrx = robotProxy->getRobotNodeSet(kc->getName());
163 kcPrx->setJointValues(startingPoint);
164 GenericIKSolverPtr ikSolver = this->IKSetup(calibration.mediumStepSize, calibration.mediumIterations, 10.0, 1.0, kcPrx);
165 Pose targetPose =
Pose(globalDestination->position, globalDestination->orientation);
166 std::vector<float> output = ikSolver->solveNoRNSUpdate(targetPose.
toEigen(), selection);
167 if (output.size() == 0)
169 std::vector<double> random = this->solveIK(kc, PoseBasePtr(
new Pose(targetPose.
toEigen())), selection, 5);
170 output = std::vector<float>(random.begin(), random.end());
178 PosePtr localPose =
PosePtr(
new Pose(framedDestination->position, framedDestination->orientation));
180 PoseBasePtr globalPose = PoseBasePtr(
new Pose(kc->getKinematicRoot()->toGlobalCoordinateSystem(localPose->toEigen())));
181 return this->solveRecursiveIK(kc, startingPoint, globalPose, selection);
186 IKCalibration calibration = calibrate();
188 RobotNodeSetPtr kcPrx = robotProxy->getRobotNodeSet(kc->getName());
189 kcPrx->setJointValues(std::vector<float>(startingPoint.begin(), startingPoint.end()));
190 GenericIKSolverPtr ikSolver = this->IKSetup(calibration.smallStepSize, calibration.smallIterations, 10, 0.5, kcPrx);
191 Pose targetPose =
Pose(globalDestination->position, globalDestination->orientation);
193 std::vector<float> output = ikSolver->solveNoRNSUpdate(targetPose.
toEigen(), selection);
194 std::vector<double> outputd = std::vector<double>(output.begin(), output.end());
201 PosePtr localPose =
PosePtr(
new Pose(framedDestination->position, framedDestination->orientation));
202 PoseBasePtr globalPose = PoseBasePtr(
new Pose(kc->getKinematicRoot()->toGlobalCoordinateSystem(localPose->toEigen())));
203 return this->solveRecursiveIK(kc, startingPoint, globalPose, selection);
206 std::vector<std::vector<double>>
KinematicSolver::solveRecursiveIK(RobotNodeSetPtr kc, std::vector<double> startingPoint, std::vector<PoseBasePtr> globalDestinations, std::vector<IKSolver::CartesianSelection> selections)
208 if (!isReachable(kc, globalDestinations[globalDestinations.size() - 1], selections[selections.size() - 1]))
210 throw LocalException(
"Desired Pose is not Reachable");
213 RobotNodeSetPtr kcPrx = robotProxy->getRobotNodeSet(kc->getName());
215 std::vector<std::vector<double>> bestResult;
216 int minSingularities = -1;
218 while ((minSingularities == -1 || minSingularities != 0) && tries < 2)
222 int failureCounter = 0;
223 int singularities = 0;
224 std::vector<std::vector<double>> result = std::vector<std::vector<double>>();
225 std::vector<float> currentStart = std::vector<float>(startingPoint.begin(), startingPoint.end());
227 for (PoseBasePtr currentDest : globalDestinations)
229 std::vector<double> temp = std::vector<double>(currentStart.begin(), currentStart.end());
232 PosePtr priorPose =
PosePtr(
new Pose(globalDestinations.at(i - 1)->position, globalDestinations.at(i - 1)->orientation));
233 PosePtr currentPose =
PosePtr(
new Pose(currentDest->position, currentDest->orientation));
234 if (priorPose->toEigen() == currentPose->toEigen() && temp.size() != 0)
242 if (currentResult.size() == 0)
245 if (failureCounter >= 1)
249 Eigen::VectorXf start = Eigen::VectorXf(temp.size());
250 Eigen::VectorXf goal = Eigen::VectorXf(temp.size());
251 std::vector<double> end = this->solveIK(kc, currentDest, selections[i], 100);
266 for (
double d : temp)
271 std::vector<double> nowStart = std::vector<double>();
273 nowStart = std::vector<double>(currentStart.begin(), currentStart.end());
274 int bestNode = getFurthestNode(kcPrx, start, goal);
275 RobotNodePtr node = kcPrx->getAllRobotNodes()[bestNode];
277 kcPrx->setJointValues(currentStart);
279 PoseBasePtr startPose = PoseBasePtr(
new Pose(node->getGlobalPose()));
280 kcPrx->setJointValues(goal);
281 PoseBasePtr endPose = PoseBasePtr(
new Pose(node->getGlobalPose()));
282 std::vector<PoseBasePtr> cp = {startPose, endPose};
283 IKCalibration calibration = calibrate();
285 for (
int i = 0; i < 25; i++)
287 PoseBasePtr poseBase = ip->getPoseAt(i * 0.04);
289 GenericIKSolverPtr ikSolver = this->IKSetup(calibration.smallStepSize, calibration.smallIterations, 5, 0.5, kcPrx);
290 DifferentialIKPtr dIK = ikSolver->getDifferentialIK();
294 dIK->setGoal(posePose->toEigen(), node, IKSolver::CartesianSelection::X);
295 dIK->setGoal(pose->toEigen(), kcPrx->getTCP(), sel);
296 kcPrx->setJointValues(std::vector<float>(nowStart.begin(), nowStart.end()));
298 if (dIK->solveIK(0.4))
301 std::vector<float> ca = kcPrx->getJointValues();
302 nowStart = std::vector<double>(ca.begin(), ca.end());
303 result.push_back(std::vector<double>(ca.begin(), ca.end()));
307 dIK->setGoal(posePose->toEigen(), node, IKSolver::CartesianSelection::Y);
308 kcPrx->setJointValues(std::vector<float>(nowStart.begin(), nowStart.end()));
309 if (dIK->solveIK(0.4))
312 std::vector<float> ca = kcPrx->getJointValues();
313 nowStart = std::vector<double>(ca.begin(), ca.end());
314 result.push_back(std::vector<double>(ca.begin(), ca.end()));
318 if (dIK->solveIK(0.4))
320 dIK->setGoal(posePose->toEigen(), node, IKSolver::CartesianSelection::Z);
321 kcPrx->setJointValues(std::vector<float>(nowStart.begin(), nowStart.end()));
323 std::vector<float> ca = kcPrx->getJointValues();
324 nowStart = std::vector<double>(ca.begin(), ca.end());
325 result.push_back(std::vector<double>(ca.begin(), ca.end()));
332 if (singularities == 1)
355 currentStart = std::vector<float>(nowStart.begin(), nowStart.end());
362 result.push_back(currentResult);
363 currentStart = std::vector<float>(currentResult.begin(), currentResult.end());
368 if (minSingularities <= 0 || singularities <= minSingularities)
370 minSingularities = singularities;
383 int failureCounter = 0;
384 RobotNodeSetPtr kcPrx = robotProxy->getRobotNodeSet(kc->getName());
385 std::vector<std::vector<double>> result = std::vector<std::vector<double>>();
386 std::vector<float> currentStart = std::vector<float>(startingPoint.begin(), startingPoint.end());
390 for (PoseBasePtr currentDest : globalDestinations)
392 std::vector<double> temp = std::vector<double>(currentStart.begin(), currentStart.end());
395 PosePtr priorPose =
PosePtr(
new Pose(globalDestinations.at(i - 1)->position, globalDestinations.at(i - 1)->orientation));
396 PosePtr currentPose =
PosePtr(
new Pose(currentDest->position, currentDest->orientation));
397 if (priorPose->toEigen() == currentPose->toEigen() && temp.size() != 0)
399 result.push_back(temp);
406 if (currentResult.size() == 0)
408 result.push_back(temp);
410 currentStart = std::vector<float>(temp.begin(), temp.end());
411 if (failureCounter > (
double)globalDestinations.size() / 20.0)
413 throw LocalException(
"Too, many faults at current calculation: " +
std::to_string(failureCounter) +
" Poses not reachable - only " +
std::to_string((
double)globalDestinations.size() / 5.0) +
" allowed!");
420 result.push_back(currentResult);
421 currentStart = std::vector<float>(currentResult.begin(), currentResult.end());
433 std::vector<IKSolver::CartesianSelection> selections = std::vector<IKSolver::CartesianSelection>();
434 for (
unsigned int i = 0; i < globalDestinations.size(); i++)
436 selections.push_back(selection);
438 return this->solveRecursiveIK(kc, startingPoint, globalDestinations, selections);
441 std::vector<std::vector<double> >
KinematicSolver::solveRecursiveIKRelative(RobotNodeSetPtr kc, std::vector<double> startingPoint, std::vector<PoseBasePtr> framedDestinations, std::vector<IKSolver::CartesianSelection> selections)
444 std::vector<PoseBasePtr> globalDestinations = std::vector<PoseBasePtr>();
445 for (PoseBasePtr framedDestination : framedDestinations)
447 PosePtr localPose =
PosePtr(
new Pose(framedDestination->position, framedDestination->orientation));
449 PoseBasePtr globalPose = PoseBasePtr(
new Pose(kc->getKinematicRoot()->toGlobalCoordinateSystem(localPose->toEigen())));
450 globalDestinations.push_back(globalPose);
452 return this->solveRecursiveIK(kc, startingPoint, globalDestinations, selections);
462 RobotNodeSetPtr kcPrx = this->setupProxy(kc,
jointAngles);
463 return PoseBasePtr(
new Pose(kcPrx->getTCP()->getGlobalPose()));
469 RobotNodeSetPtr kcPrx = this->setupProxy(kc,
jointAngles);
470 return PoseBasePtr(
new Pose(kcPrx->getKinematicRoot()->toLocalCoordinateSystem(kcPrx->getTCP()->getGlobalPose())));
493 return this->solveIK(rns, pose, cs, 50).size() != 0;
498 if (currentRns != rns->getName())
500 currentRns = rns->getName();
501 this->syncRobotPrx();
508 for (RobotNodePtr node : robot->getRobotNodes())
510 this->robotProxy->getRobotNode(node->getName())->setJointValue(node->getJointValue());
517 GenericIKSolverPtr KinematicSolver::IKSetup(
double jacStepSize,
int IKIterations,
double vectorError,
double orientationError, RobotNodeSetPtr kc)
519 GenericIKSolverPtr ikSolver = GenericIKSolverPtr(
new GenericIKSolver(kc, JacobiProvider::eSVDDamped));
520 ikSolver->setupJacobian(jacStepSize, IKIterations);
521 ikSolver->setMaximumError(vectorError, orientationError);
525 RobotNodeSetPtr KinematicSolver::setupProxy(RobotNodeSetPtr kc, std::vector<double>
jointAngles)
527 RobotNodeSetPtr kcPrx = robotProxy->getRobotNodeSet(kc->getName());
529 kcPrx->setJointValues(jointValues);
533 KinematicSolver::IKCalibration KinematicSolver::calibrate()
536 if (robot->getName() !=
"Armar3" && robot->getName() !=
"Armar4" && robot->getName() !=
"Armar6")
538 return this->IKCalibrationMap.at(
"Armar3");
542 return this->IKCalibrationMap.at(robot->getName());
546 double KinematicSolver::getMaxDistance(Eigen::Vector3f destination, std::vector<std::vector<double> >
jointAngles, RobotNodeSetPtr rns)
551 PoseBasePtr pose = doForwardKinematicRelative(rns, ja);
552 double distance =
sqrt(pow(pose->position->x - destination[0], 2) + pow(pose->position->y - destination[1], 2) + pow(pose->position->z - destination[2], 2));
561 int KinematicSolver::getFurthestNode(RobotNodeSetPtr rns, Eigen::VectorXf startConfig, Eigen::VectorXf endConfig)
564 int best = rns->getSize() - 1;
565 rns->setJointValues(startConfig);
566 std::vector<Eigen::Vector3f> startPoses = std::vector<Eigen::Vector3f>();
567 std::vector<Eigen::Vector3f> endPoses = std::vector<Eigen::Vector3f>();
568 for (RobotNodePtr node : rns->getAllRobotNodes())
570 Eigen::Vector3f currentPose = Eigen::Vector3f();
571 currentPose[0] = node->getGlobalPose()(0, 3);
572 currentPose[1] = node->getGlobalPose()(1, 3);
573 currentPose[2] = node->getGlobalPose()(2, 3);
574 startPoses.push_back(currentPose);
576 rns->setJointValues(endConfig);
577 for (RobotNodePtr node : rns->getAllRobotNodes())
579 Eigen::Vector3f currentPose = Eigen::Vector3f();
580 currentPose[0] = node->getGlobalPose()(0, 3);
581 currentPose[1] = node->getGlobalPose()(1, 3);
582 currentPose[2] = node->getGlobalPose()(2, 3);
583 endPoses.push_back(currentPose);
585 for (
unsigned int i = 0; i < startPoses.size(); i++)