InclineSensor.cpp

Go to the documentation of this file.
00001 /*************************************************************************
00002  *                                                                       *
00003  * Open Physics Abstraction Layer                                        *
00004  * Copyright (C) 2004-2005                                               *
00005  * Alan Fischer  alan.fischer@gmail.com                                  *
00006  * Andres Reinot  andres@reinot.com                                      *
00007  * Tyler Streeter  tylerstreeter@gmail.com                               *
00008  * All rights reserved.                                                  *
00009  * Web: opal.sourceforge.net                                             *
00010  *                                                                       *
00011  * This library is free software; you can redistribute it and/or         *
00012  * modify it under the terms of EITHER:                                  *
00013  *   (1) The GNU Lesser General Public License as published by the Free  *
00014  *       Software Foundation; either version 2.1 of the License, or (at  *
00015  *       your option) any later version. The text of the GNU Lesser      *
00016  *       General Public License is included with this library in the     *
00017  *       file license-LGPL.txt.                                          *
00018  *   (2) The BSD-style license that is included with this library in     *
00019  *       the file license-BSD.txt.                                       *
00020  *                                                                       *
00021  * This library is distributed in the hope that it will be useful,       *
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
00024  * license-LGPL.txt and license-BSD.txt for more details.                *
00025  *                                                                       *
00026  *************************************************************************/
00027 
00028 #include "InclineSensor.h"
00029 #include "Simulator.h"
00030 
00031 namespace opal
00032 {
00033         InclineSensor::InclineSensor()
00034         {
00035                 // "mData" is initialized in its own constructor.
00036                 // "mLocalReferenceVec" is initialized in its own constructor.
00037                 // "mInitGlobalReferenceVec" is initialized in its own constructor.
00038         }
00039 
00040         InclineSensor::~InclineSensor()
00041         {
00042         }
00043 
00044         void InclineSensor::init(const InclineSensorData& data)
00045         {
00046                 Sensor::init();
00047                 mData = data;
00048 
00049                 // Define the current setup as zero degrees.
00050                 setupInternalVectors();
00051         }
00052 
00053         const InclineSensorData& InclineSensor::getData()const
00054         {
00055                 return mData;
00056         }
00057 
00058         real InclineSensor::getAngle()
00059         {
00060                 if (!mData.enabled || !mData.solid)
00061                 {
00062                         return 0;
00063                 }
00064 
00065                 // By this time setupInternalVectors should have been called, so 
00066                 // the mLocalReferenceVec and mInitGlobalReferenceVec vectors are 
00067                 // valid.
00068 
00069                 // Let's call the plane orthogonal to the rotation axis the 
00070                 // "plane of rotation."  The local reference vector is currently on 
00071                 // the plane of rotation.  We need to get the initial global 
00072                 // reference vector projected onto the plane of rotation.
00073 
00074                 Vec3r currentGlobalReferenceVec = mData.solid->getTransform() * 
00075                         mLocalReferenceVec;
00076 
00077                 if (areCollinear(mInitGlobalReferenceVec, currentGlobalReferenceVec))
00078                 {
00079                         // Return zero degrees if the initial global reference vector 
00080                         // is collinear with the current global reference vector.
00081                         return 0;
00082                 }
00083 
00084                 Vec3r tempVec = cross(mData.axis, mInitGlobalReferenceVec);
00085                 Vec3r u = cross(mData.axis, tempVec);
00086 
00087                 // Now 'u' should be on the plane of rotation.  We just need to 
00088                 // project the initial global reference vector onto it.
00089 
00090                 Vec3r projInitGlobalReferenceVec = project(u, 
00091                         mInitGlobalReferenceVec);
00092 
00093                 // Now calculate the angle between the projected global reference 
00094                 // vector and the current global reference vector.
00095                 real angle = angleBetween(projInitGlobalReferenceVec, 
00096                         currentGlobalReferenceVec);
00097 
00098                 return angle;
00099         }
00100 
00101         void InclineSensor::setEnabled(bool e)
00102         {
00103                 //if (!mInitCalled)
00104                 //{
00105                 //      return;
00106                 //}
00107 
00108                 mData.enabled = e;
00109         }
00110 
00111         bool InclineSensor::isEnabled()const
00112         {
00113                 return mData.enabled;
00114         }
00115 
00116         void InclineSensor::setAxis(const Vec3r& axis)
00117         {
00118                 if (!mData.solid)
00119                 {
00120                         return;
00121                 }
00122 
00123                 mData.axis = axis;
00124 
00125                 // Redefine the current setup as zero degrees.
00126                 setupInternalVectors();
00127         }
00128 
00129         const Vec3r& InclineSensor::getAxis()
00130         {
00131                 return mData.axis;
00132         }
00133 
00134         SensorType InclineSensor::getType()const
00135         {
00136                 return mData.getType();
00137         }
00138 
00139         void InclineSensor::setTransform(const Matrix44r& t)
00140         {
00141                 mData.transform = t;
00142         }
00143 
00144         const Matrix44r& InclineSensor::getTransform()const
00145         {
00146                 return mData.transform;
00147         }
00148 
00149         void InclineSensor::setName(const std::string& name)
00150         {
00151                 mData.name = name;
00152         }
00153 
00154         const std::string& InclineSensor::getName()const
00155         {
00156                 return mData.name;
00157         }
00158 
00159         void InclineSensor::internal_update()
00160         {
00161                 if (mData.enabled && mData.solid)
00162                 {
00163                         // Do nothing.
00164                 }
00165         }
00166 
00167         bool InclineSensor::internal_dependsOnSolid(Solid* s)
00168         {
00169                 if (s == mData.solid)
00170                 {
00171                         return true;
00172                 }
00173                 else
00174                 {
00175                         return false;
00176                 }
00177         }
00178 
00179         void InclineSensor::setupInternalVectors()
00180         {
00181                 if (!mData.solid)
00182                 {
00183                         return;
00184                 }
00185 
00186                 // We need to calculate a local reference vector that's orthogonal 
00187                 // to the rotation axis.
00188 
00189                 // This temporary vector can be anything as long as its not 
00190                 // collinear with the rotation axis.
00191                 Vec3r tempVec(1, 0, 0);
00192 
00193                 if (areCollinear(mData.axis, tempVec))
00194                 {
00195                         // Pick a new tempVec.
00196                         tempVec.set(0, 1, 0);
00197                 }
00198 
00199                 // Now we can get the orthogonal reference vector.
00200                 mLocalReferenceVec = cross(mData.axis, tempVec);
00201 
00202                 // Also store a copy of this reference vector in its initial global 
00203                 // representation.
00204                 mInitGlobalReferenceVec = mData.solid->getTransform() * 
00205                         mLocalReferenceVec;
00206         }
00207 }

Generated on Tue May 16 17:49:51 2006 for OPAL by  doxygen 1.4.6-NO