00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <robot/control/kinematics/LeastNormIKSolver>
00026
00027 using robot::control::kinematics::LeastNormIKSolver;
00028
00029 using base::Vector;
00030 using base::Orient;
00031 using robot::control::kinematics::MPPseudoInvSolver;
00032
00033
00034 LeastNormIKSolver::LeastNormIKSolver()
00035 {
00036 solver = ref<MPPseudoInvSolver>(NewObj MPPseudoInvSolver());
00037 }
00038
00039
00040 const Real small = 5.0e-05;
00041
00042
00043 Vector LeastNormIKSolver::solve(const Vector& dx, const Vector& x, const Vector& q,
00044 const base::Matrix& J,
00045 OptimizationMethod optMethod,
00046 OptimizationCriterion optCriterion,
00047 OptimizationConstraints optConstraints,
00048 base::Orient::Representation orientationRepresentation)
00049 {
00050 if (optMethod==DefaultMethod) optMethod=PseudoInv;
00051 if (optCriterion==DefaultCriterion) optCriterion=LeastNorm;
00052 if (optConstraints.test(DefaultConstraints)) optConstraints.reset();
00053
00054 Assertm(optCriterion==LeastNorm, "criterion is leastnorm (no optimization involved for this method)");
00055 Assertm(optMethod==PseudoInv, "method is pseudo-inverse (no other method supported)");
00056 Assertm(optConstraints.none(), "no constraints (none supported)");
00057
00058 const Int N = J.size1();
00059 const Int M = J.size2();
00060
00061 Assert(dx.size() == x.size());
00062 Assert(q.size() == M);
00063
00064
00065
00066 Vector newdx;
00067 if (N>3) {
00068 Vector dpos(3);
00069 dpos = vectorRange(dx,Range(0,3));
00070 Orient orient(vectorRange(x,Range(3,x.size())),orientationRepresentation);
00071 Orient dorient(vectorRange(dx,Range(3,dx.size())),orientationRepresentation);
00072 Vector omega(3);
00073 omega = orient.getBinv()*Vector(dorient);
00074 newdx.resize(6);
00075 vectorRange(newdx,Range(0,3)) = dpos;
00076 vectorRange(newdx,Range(3,6)) = omega;
00077 }
00078 else
00079 newdx.reset(dx);
00080
00081
00082 if (base::equals(dx,zeroVector(N),small))
00083 return zeroVector(M);
00084
00085
00086 return solver->solve(J, newdx);
00087 }