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
00021 RigidBodyInertia inertia(0.3, Vector(0.0, 0.1, 0.0), RotationalInertia(0.005, 0.001, 0.001));
00022
00023
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
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
00056 tree = Tree();
00057 tree.addChain(chain1, tree.getRootSegment()->first);
00058 tree.addChain(chain2, tree.getRootSegment()->first);
00059
00060
00061 m=1.0, Iz=0.05, L=0.5;
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
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
00111 CPPUNIT_ASSERT_EQUAL(nt, n1+n2);
00112
00113 JntArray q(nt), qd(nt), qdd(nt), tau(nt);
00114 JntArray q1(n1), qd1(n1), qdd1(n1), tau1(n1);
00115 JntArray q2(n2), qd2(n2), qdd2(n2), tau2(n2);
00116
00117 unsigned int iterations = 100;
00118 while(iterations-- > 0) {
00119
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
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
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
00145
00146 unsigned int dof = ytree.getNrOfJoints();
00147 CPPUNIT_ASSERT_EQUAL(dof, (unsigned int)3);
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
00157 for(unsigned int i=0; i<dof; i++)
00158 random(q(i)), random(qd(i)), random(qdd(i));
00159
00160
00161 CPPUNIT_ASSERT_EQUAL((int)SolverI::E_NOERROR, solver.CartToJnt(q, qd, qdd, WrenchMap(), tau));
00162
00163
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
00174 CPPUNIT_ASSERT_EQUAL(tau, eff);
00175 }
00176
00177 }