Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

base/OrientTest.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002   Copyright (C)2002 David Jung <opensim@pobox.com>
00003 
00004   This program/file is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008   
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details. (http://www.gnu.org)
00013   
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017   
00018   $Id: OrientTest.cpp 1029 2004-02-11 20:45:54Z jungd $
00019   $Revision: 1.6 $
00020   $Date: 2004-02-11 15:45:54 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #include <base/OrientTest>
00026 
00027 #include <base/Math>
00028 
00029 #include <base/Transform>
00030 
00031 using base::OrientTest;
00032 
00033 using base::Math;
00034 using base::Quat4;
00035 using base::Matrix;
00036 using base::Vector;
00037 using base::Transform;
00038 
00039 
00040 
00041 OrientTest::OrientTest()
00042   : m(3,3)
00043 {
00044 }
00045 
00046 
00047 void OrientTest::setUp() 
00048 { 
00049 
00050 }
00051   
00052 
00053 void OrientTest::tearDown()
00054 { 
00055 }
00056 
00057 
00058 
00059 void OrientTest::testQuatMat()
00060 {
00061   // test a basic Quat4 rotation
00062   Quat4 qr(Vector3(1,1,0),consts::Pi/2.0);
00063   Point3 up(1,0,0);
00064   CPPUNIT_ASSERT( qr.rotate(up).equals(Point3(0.5,0.5,-0.707107),1e-5) );
00065 
00066 
00067   // test some basic interconversions first
00068   Quat4 rotx45(Vector3(1,0,0),Math::degToRad(45));
00069   Orient o(rotx45);
00070 
00071   CPPUNIT_ASSERT( o.getQuat4() == rotx45 );
00072 
00073   m.reset( o.getRotationMatrix() );
00074   CPPUNIT_ASSERT(m.size1() == 3);
00075   CPPUNIT_ASSERT(m.size2() == 3);
00076 
00077   Orient o2(m);
00078 
00079   Matrix m2( o2.getRotationMatrix() );
00080   
00081   CPPUNIT_ASSERT( base::equals(m2,m) );
00082 
00083 
00084   Quat4 q(Vector3(1,1,0),consts::Pi/4.0);
00085 
00086   // test two paths for getting the same matrix into an Orient
00087   Orient oq(q);
00088   Matrix4 oqm(oq.getRotationMatrix3()); 
00089   Orient  om = Matrix3(oqm);
00090   Matrix4 omm(om.getRotationMatrix3());
00091   CPPUNIT_ASSERT( omm.equals(oqm) );
00092  
00093   // test Quat4 & Orient to matrix conversions are identical
00094   Orient q3(q);
00095   Matrix3 m3(q3.getRotationMatrix3());
00096   CPPUNIT_ASSERT( Matrix4(m3).equals(Matrix4(q)) );
00097   
00098 
00099   // test quat->Mat->quat
00100   Orient q3m(m3);
00101   Orient q3mq(q3m.getQuat4());
00102 
00103   Quat4 q31(q3.getQuat4());
00104   Quat4 q32(q3mq.getQuat4());
00105   Point3 u(1,2,3);
00106   Point3 u1(q31.rotate(u));
00107   Point3 u2(q32.rotate(u));
00108   Point3 u3(m3*u);
00109   Point3 u4(q.rotate(u));
00110 
00111   CPPUNIT_ASSERT( u1.equals(u2) );
00112   CPPUNIT_ASSERT( u1.equals(u3) );
00113   CPPUNIT_ASSERT( u1.equals(u4) );
00114   
00115   // test quat inverse
00116   Quat4 q4(Vector3(1,2,4), consts::Pi/3.0);
00117   Quat4 q4i( inverse(q4) );
00118   CPPUNIT_ASSERT( q4i.rotate(q4.rotate(u)).equals(u) );
00119   Matrix4 m4(q4);
00120   Matrix4 m4i(q4i);
00121   CPPUNIT_ASSERT( (m4i*m4*u).equals(u) );
00122   Matrix4 m4id( m4i*m4 );
00123   Matrix4 I; I.setIdentity();
00124   CPPUNIT_ASSERT( m4id.equals(I) );
00125 
00126   // test orient inverse
00127   Orient o4 = Quat4(Vector3(1,2,4), consts::Pi/3.0);
00128   Orient o4i = inverse(o4.getQuat4());
00129   CPPUNIT_ASSERT( o4i.rotate(o4.rotate(u)).equals(u) );
00130   Matrix4 om4(o4);
00131   Matrix4 om4i(o4i);
00132   CPPUNIT_ASSERT( (om4i*om4*u).equals(u) );
00133   Matrix4 om4id( om4i*om4 );
00134   CPPUNIT_ASSERT( om4id.equals(I) );
00135 }
00136 
00137 
00138 
00139 void OrientTest::testTransform()
00140 {
00141   Quat4 q(0.158724,0.508859,0.458874,0.710847);
00142   Orient o(q);
00143   Transform t(q);
00144   
00145   Point3 p(1,2,3);
00146   CPPUNIT_ASSERT( q.rotate(p).equals(o.rotate(p)) );
00147   CPPUNIT_ASSERT( q.rotate(p).equals(t.rotate(p)) );
00148 }
00149 
00150 
00151 
00152 void OrientTest::testEulerRPY()
00153 {
00154   // construct a EulerRPY manually as rotations about
00155   //  axes and see if we get what we expect
00156   
00157   Real roll = consts::Pi/3.1;
00158   Real pitch = consts::Pi/5.1;
00159   Real yaw = consts::Pi/2.1;
00160   
00161   // construct rotation about X, Y, Z axes in that order (static/fixed frames)
00162   Transform rotx = Quat4(Vector3(1,0,0), roll);
00163   Transform roty = Quat4(Vector3(0,1,0), pitch);
00164   Transform rotz = Quat4(Vector3(0,0,1), yaw);
00165   Transform qt( rotz*roty*rotx );
00166   
00167   Orient rpyt(roll,pitch, yaw);
00168   
00169   Point3 p(1,2,3); // test point to transform
00170   Point3 pqt( qt.rotate(p) ); // transform using manually constructed quat
00171   Point3 prpyt( rpyt.rotate(p) ); // transform using RPY
00172   Point3 pit( rotz.rotate(roty.rotate(rotx.rotate(p))) ); // transform via sucessive application of individual rotations in order
00173   
00174   CPPUNIT_ASSERT( pqt.equals(prpyt) );
00175   CPPUNIT_ASSERT( pqt.equals(pit) );
00176 
00177   
00178   // convert to a Quat and back and test preservation
00179   Orient q(rpyt);
00180   q.changeRepresentation(Orient::Quat);
00181   CPPUNIT_ASSERT( q.rotate(p).equals(pqt) ); // check is same transformation
00182   q.changeRepresentation(Orient::EulerRPY);
00183   
00184   CPPUNIT_ASSERT( q.equals(rpyt) );
00185 
00186   // convert to matrix and back
00187   q.changeRepresentation(Orient::Mat);
00188   CPPUNIT_ASSERT( Point3(q.getRotationMatrix3() * p).equals(pqt) ); // check is same transformation
00189   q.changeRepresentation(Orient::EulerRPY);
00190 
00191   CPPUNIT_ASSERT( q.equals(rpyt) );
00192   
00193   // convert to EulerZYXs and back
00194   q.changeRepresentation(Orient::EulerZYXs);
00195   q.changeRepresentation(Orient::EulerRPY);
00196   CPPUNIT_ASSERT( q.equals(rpyt) );
00197   
00198   // Try converting from EulerRPY to Quat, to Mat and back
00199   Orient o1(1.57071,-1.00007,0.800039);
00200   Orient o2(o1); 
00201   o2.changeRepresentation(Orient::Quat);
00202   o2.changeRepresentation(Orient::Mat);
00203   o2.changeRepresentation(Orient::EulerRPY);
00204   CPPUNIT_ASSERT( o1.equals(o2) );
00205   
00206   // try another conversion from RPY->Quat and back at gymbal-lock config
00207   Orient o3(0,0,1.5708);
00208   Orient o4(o3);
00209   o3.changeRepresentation(Orient::Quat);
00210   o3.changeRepresentation(Orient::EulerRPY);
00211   CPPUNIT_ASSERT( o3.equals(o4) );
00212 }
00213 
00214 
00215 
00216 
00217 
00218 #ifdef DEBUG
00219 CPPUNIT_TEST_SUITE_REGISTRATION( OrientTest );
00220 #endif
00221 

Generated on Thu Jul 29 15:56:08 2004 for OpenSim by doxygen 1.3.6