treeinvdyntest.cpp
Go to the documentation of this file.
00001 #include "treeinvdyntest.hpp"
00002 #include <kinfam_io.hpp>
00003 #include <frames_io.hpp>
00004 #include <chainidsolver_recursive_newton_euler.hpp>
00005 #include <treeidsolver_recursive_newton_euler.hpp>
00006 #include <time.h>
00007 #include <cmath>
00008 
00009 
00010 CPPUNIT_TEST_SUITE_REGISTRATION( TreeInvDynTest );
00011 
00012 using namespace KDL;
00013 using std::cout;
00014 using std::endl;
00015 
00016 void TreeInvDynTest::setUp()
00017 {
00018     srand( (unsigned)time( NULL ));
00019 
00020     //spatial inertia (just to test dynamics)
00021     RigidBodyInertia inertia(0.3, Vector(0.0, 0.1, 0.0), RotationalInertia(0.005, 0.001, 0.001));
00022 
00023     //create chain #1
00024     chain1.addSegment(Segment("Segment 11", Joint("Joint 11", Joint::RotZ),
00025                               Frame(Vector(0.0,0.0,0.0)), inertia));
00026     chain1.addSegment(Segment("Segment 12", Joint("Joint 12", Joint::RotX),
00027                               Frame(Vector(0.0,0.0,0.9)), inertia));
00028     chain1.addSegment(Segment("Segment 13", Joint("Joint 13", Joint::None),
00029                               Frame(Vector(-0.4,0.0,0.0))));
00030     chain1.addSegment(Segment("Segment 14", Joint("Joint 14", Joint::RotX),
00031                               Frame(Vector(0.0,0.0,1.2)), inertia));
00032     chain1.addSegment(Segment("Segment 15", Joint("Joint 15", Joint::None),
00033                               Frame(Vector(0.4,0.0,0.0)), inertia));
00034     chain1.addSegment(Segment("Segment 16", Joint("Joint 16", Joint::RotZ),
00035                               Frame(Vector(0.0,0.0,1.4)), inertia));
00036     chain1.addSegment(Segment("Segment 17", Joint("Joint 17", Joint::RotX),
00037                               Frame(Vector(0.0,0.0,0.0)), inertia));
00038     chain1.addSegment(Segment("Segment 18", Joint("Joint 18", Joint::RotZ),
00039                               Frame(Vector(0.0,0.0,0.4)), inertia));
00040     chain1.addSegment(Segment("Segment 19", Joint("Joint 19", Joint::None),
00041                               Frame(Vector(0.0,0.0,0.0)), inertia));
00042 
00043     //create chain #2
00044     chain2.addSegment(Segment("Segment 21", Joint("Joint 21", Joint::RotZ),
00045                               Frame(Vector(0.0,0.0,0.5)), inertia));
00046     chain2.addSegment(Segment("Segment 22", Joint("Joint 22", Joint::RotX),
00047                               Frame(Vector(0.0,0.0,0.4)), inertia));
00048     chain2.addSegment(Segment("Segment 23", Joint("Joint 23", Joint::RotX),
00049                               Frame(Vector(0.0,0.0,0.3)), inertia));
00050     chain2.addSegment(Segment("Segment 24", Joint("Joint 24", Joint::RotX),
00051                               Frame(Vector(0.0,0.0,0.2)), inertia));
00052     chain2.addSegment(Segment("Segment 25", Joint("Joint 25", Joint::RotZ),
00053                               Frame(Vector(0.0,0.0,0.1)), inertia));
00054 
00055     //create tree as two chains attached to the root
00056     tree = Tree();
00057     tree.addChain(chain1, tree.getRootSegment()->first);
00058     tree.addChain(chain2, tree.getRootSegment()->first);
00059 
00060     //create a simple "y-shaped" tree
00061     m=1.0, Iz=0.05, L=0.5; //geometric and dynamic parameters
00062     Segment s1("S1", Joint("q1", Joint::RotZ), Frame(), RigidBodyInertia(m, Vector(L,0,0), RotationalInertia(0,0,Iz)));
00063     Segment s2("S2", Joint("q2", Vector(L,0,0), Vector(0,0,1), Joint::RotAxis), Frame(Vector(L,0,0)), RigidBodyInertia(m, Vector(L/2,0,0), RotationalInertia(0,0,Iz)));
00064     Segment s3("S3", Joint("q3", Vector(2*L,0,0), Vector(0,0,1), Joint::RotAxis), Frame(Vector(2*L,0,0)), RigidBodyInertia(m, Vector(L/2,0,0), RotationalInertia(0,0,Iz)));
00065     ytree = Tree("root");
00066     ytree.addSegment(s1, "root");
00067     ytree.addSegment(s2, "S1");
00068     ytree.addSegment(s3, "S1");
00069 }
00070 
00071 
00072 void TreeInvDynTest::tearDown() { }
00073 
00074 
00075 void TreeInvDynTest::UpdateTreeTest() {
00076   // std::cout << "Tree: " << endl << tree2str(tree) << endl; //NOTE: tree2str is not available as I implemented it in another "parallel" commit
00077   std::cout << "\nTree: " << endl << tree << endl;
00078 
00079   Tree temp_tree(tree);
00080   TreeIdSolver_RNE solver(temp_tree, Vector::Zero());
00081   JntArray q, qd, qdd, tau;
00082 
00083   CPPUNIT_ASSERT_EQUAL((int)SolverI::E_SIZE_MISMATCH, solver.CartToJnt(q, qd, qdd, WrenchMap(), tau));
00084   q.resize(temp_tree.getNrOfJoints());
00085   CPPUNIT_ASSERT_EQUAL((int)SolverI::E_SIZE_MISMATCH, solver.CartToJnt(q, qd, qdd, WrenchMap(), tau));
00086   qd.resize(temp_tree.getNrOfJoints());
00087   CPPUNIT_ASSERT_EQUAL((int)SolverI::E_SIZE_MISMATCH, solver.CartToJnt(q, qd, qdd, WrenchMap(), tau));
00088   qdd.resize(temp_tree.getNrOfJoints());
00089   CPPUNIT_ASSERT_EQUAL((int)SolverI::E_SIZE_MISMATCH, solver.CartToJnt(q, qd, qdd, WrenchMap(), tau));
00090   tau.resize(temp_tree.getNrOfJoints());
00091   CPPUNIT_ASSERT_EQUAL((int)SolverI::E_NOERROR, solver.CartToJnt(q, qd, qdd, WrenchMap(), tau));
00092 
00093   temp_tree.addSegment(Segment("extra"), temp_tree.getRootSegment()->first);
00094   CPPUNIT_ASSERT_EQUAL((int)SolverI::E_NOT_UP_TO_DATE, solver.CartToJnt(q, qd, qdd, WrenchMap(), tau));
00095   solver.updateInternalDataStructures();
00096   CPPUNIT_ASSERT_EQUAL((int)SolverI::E_NOERROR, solver.CartToJnt(q, qd, qdd, WrenchMap(), tau));
00097 }
00098 
00099 
00100 void TreeInvDynTest::TwoChainsTest() {
00101   Vector gravity(0,0,-9.8);
00102   TreeIdSolver_RNE solver(tree, gravity);
00103   ChainIdSolver_RNE solver1(chain1, gravity);
00104   ChainIdSolver_RNE solver2(chain2, gravity);
00105 
00106   unsigned int nt = tree.getNrOfJoints();
00107   unsigned int n1 = chain1.getNrOfJoints();
00108   unsigned int n2 = chain2.getNrOfJoints();
00109 
00110   //Check that sizes are consistent -- otherwise following code does not make sense!
00111   CPPUNIT_ASSERT_EQUAL(nt, n1+n2);
00112 
00113   JntArray q(nt), qd(nt), qdd(nt), tau(nt); //data related to tree
00114   JntArray q1(n1), qd1(n1), qdd1(n1), tau1(n1); //data related to chain1
00115   JntArray q2(n2), qd2(n2), qdd2(n2), tau2(n2); //data related to chain2
00116 
00117   unsigned int iterations = 100;
00118   while(iterations-- > 0) {
00119     //Randomize joint vectors
00120     for(unsigned int i=0; i<nt; i++) random(q(i)), random(qd(i)), random(qdd(i));
00121     for(unsigned int i=0; i<n1; i++) q1(i)=q(i), qd1(i)=qd(i), qdd1(i)=qdd(i);
00122     for(unsigned int i=0; i<n2; i++) q2(i)=q(i+n1), qd2(i)=qd(i+n1), qdd2(i)=qdd(i+n1);
00123 
00124     //Evaluate efforts
00125     CPPUNIT_ASSERT_EQUAL((int)SolverI::E_NOERROR, solver.CartToJnt(q, qd, qdd, WrenchMap(), tau));
00126     CPPUNIT_ASSERT_EQUAL((int)SolverI::E_NOERROR, solver1.CartToJnt(q1, qd1, qdd1, Wrenches(chain1.getNrOfSegments()), tau1));
00127     CPPUNIT_ASSERT_EQUAL((int)SolverI::E_NOERROR, solver2.CartToJnt(q2, qd2, qdd2, Wrenches(chain2.getNrOfSegments()), tau2));
00128 
00129     //compare efforts
00130     JntArray tau12(tau.rows());
00131     for(unsigned int i=0; i<n1; i++) tau12(i) = tau1(i);
00132     for(unsigned int i=0; i<n2; i++) tau12(i+n1) = tau2(i);
00133     CPPUNIT_ASSERT_EQUAL(tau, tau12);
00134   }
00135 }
00136 
00137 
00138 void TreeInvDynTest::YTreeTest() {
00139   std::cout << "\nY-shaped tree: " << endl << ytree << endl;
00140 
00141   double g = 9.8;
00142   TreeIdSolver_RNE solver(ytree, Vector(0,-g,0));
00143 
00144   //Following is just a check in case the model is modified. In this case the
00145   //analytic model derived using Euler-Lagrange equations would not be valid.
00146   unsigned int dof = ytree.getNrOfJoints();
00147   CPPUNIT_ASSERT_EQUAL(dof, (unsigned int)3); // The analytic euler-lagrange model was derived for a specific 3-dof model
00148 
00149   JntArray q(dof), qd(dof), qdd(dof), tau(dof), eff(dof);
00150 
00151   double mLL = m*L*L;
00152   double Ie = Iz + 0.25*mLL;
00153 
00154   unsigned int iterations = 100;
00155   while(iterations-- > 0) {
00156     //Randomize joint vectors
00157     for(unsigned int i=0; i<dof; i++)
00158       random(q(i)), random(qd(i)), random(qdd(i));
00159 
00160     //Evaluate efforts using the numerical solver
00161     CPPUNIT_ASSERT_EQUAL((int)SolverI::E_NOERROR, solver.CartToJnt(q, qd, qdd, WrenchMap(), tau));
00162 
00163     //Evaluate efforts using the analytic model derived using Euler-Lagrange equations
00164     double s2 = std::sin(q(1)), c2 = std::cos(q(1));
00165     double s3 = std::sin(q(2)), c3 = std::cos(q(2));
00166     double c1 = std::cos(q(0)), c12 = std::cos(q(0)+q(1)), c13 = std::cos(q(0)+q(2));
00167     eff(0) = (3*Iz+6.5*mLL+mLL*c2+2*mLL*c3) * qdd(0) + (Ie+0.5*mLL*c2) * qdd(1)
00168             + (Ie+mLL*c3) * qdd(2) - 0.5*mLL*s2*qd(1)*qd(1) - mLL*s3*qd(2)*qd(2)
00169             - mLL*s2*qd(0)*qd(1) - 2*mLL*s3*qd(0)*qd(2) + m*g*(4*L*c1+0.5*L*c12+0.5*L*c13);
00170     eff(1) = (Ie+0.5*mLL*c2) * qdd(0) + Ie * qdd(1) + 0.5*mLL*s2*qd(0)*qd(0) + 0.5*m*g*L*c12;
00171     eff(2) = (Ie+mLL*c3) * qdd(0) + Ie * qdd(2) + mLL*s3*qd(0)*qd(0) + 0.5*m*g*L*c13;
00172 
00173     //compare efforts
00174     CPPUNIT_ASSERT_EQUAL(tau, eff);
00175   }
00176 
00177 }


orocos_kdl
Author(s):
autogenerated on Fri Jun 14 2019 19:33:23