ServoMotor.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 "ServoMotor.h"
00029 
00030 namespace opal
00031 {
00032     ServoMotor::ServoMotor()
00033             : Motor()
00034     {
00035         // "mData" will be initialized in its own constructor.
00036     }
00037 
00038     ServoMotor::~ServoMotor()
00039     {
00040         // We must set the Joint's desired vel and max force to 0 since
00041         // this Motor won't apply to it anymore.  This is only necessary
00042         // if this Motor is enabled.
00043         if ( mData.enabled && mData.joint )
00044         {
00045             mData.joint->internal_setDesiredVel( mData.jointAxisNum, 0 );
00046             mData.joint->internal_setMaxTorque( mData.jointAxisNum, 0 );
00047         }
00048     }
00049 
00050     void ServoMotor::init( const ServoMotorData& data )
00051     {
00052         if ( mInitCalled )
00053         {
00054             // If the Servo is already in operation, we first need to
00055             // set the old Joint's desired vel and max force to 0.  The
00056             // following function call will automatically handle this
00057             // when set to false.
00058             setEnabled( false );
00059         }
00060 
00061         assert( data.joint );
00062         assert( data.jointAxisNum >= 0 &&
00063                 data.jointAxisNum < data.joint->getNumAxes() );
00064         Motor::init();
00065         assert( data.joint->isRotational( data.jointAxisNum ) );
00066         mData = data;
00067         setEnabled( mData.enabled );
00068     }
00069 
00070     const ServoMotorData& ServoMotor::getData() const
00071     {
00072         return mData;
00073     }
00074 
00075     MotorType ServoMotor::getType() const
00076     {
00077         return mData.getType();
00078     }
00079 
00080     void ServoMotor::setName( const std::string& name )
00081     {
00082         mData.name = name;
00083     }
00084 
00085     const std::string& ServoMotor::getName() const
00086     {
00087         return mData.name;
00088     }
00089 
00090     bool ServoMotor::isEnabled() const
00091     {
00092         return mData.enabled;
00093     }
00094 
00095     void ServoMotor::setEnabled( bool e )
00096     {
00097         //if (!mInitCalled)
00098         //{
00099         //      return;
00100         //}
00101 
00102         mData.enabled = e;
00103 
00104         if ( mData.joint )
00105         {
00106             if ( e )
00107             {
00108                 mData.joint->internal_setDesiredVel( mData.jointAxisNum,
00109                                                      mData.desiredVel );
00110                 mData.joint->internal_setMaxTorque( mData.jointAxisNum,
00111                                                     mData.maxTorque );
00112             }
00113             else
00114             {
00115                 mData.joint->internal_setDesiredVel( mData.jointAxisNum, 0 );
00116                 mData.joint->internal_setMaxTorque( mData.jointAxisNum, 0 );
00117             }
00118         }
00119     }
00120 
00121     void ServoMotor::internal_update()
00122     {
00123         if ( mData.enabled && mData.joint )
00124         {
00125             // Make sure both Solids are awake at this point.
00126             mData.joint->wakeSolids();
00127 
00128             if ( DESIRED_ANGLE_MODE == mData.mode )
00129             {
00130                 // No longer support linear degrees of freedom.
00131                 //if (true == mData.joint->isRotational(mData.jointAxisNum))
00132                 //{
00133                 real velocity = mData.desiredAngle -
00134                                 mData.joint->getAngle( mData.jointAxisNum );
00135                 if ( velocity > 180.0 )
00136                     velocity = -360 + velocity;
00137                 if ( velocity < -180.0 )
00138                     velocity = 360 + velocity;
00139                 mData.joint->internal_setDesiredVel( mData.jointAxisNum,
00140                                                      mData.restoreSpeed * velocity );
00141                 //}
00142                 //else
00143                 //{
00144                 //      // This axis must be a linear degree of freedom.
00145                 //      real velocity = mData.desiredPos -
00146                 //              mData.joint->getState(mData.jointAxisNum);
00147                 //      mData.joint->internal_setDesiredVel(mData.jointAxisNum,
00148                 //              mData.restoreSpeed * velocity);
00149                 //}
00150             }
00151             else
00152             {
00153                 // Nothing to do for desired velocity mode; the Joint's
00154                 // desired velocity should already handle this.
00155             }
00156         }
00157     }
00158 
00159     void ServoMotor::setDesiredAngle( real a )
00160     {
00161                 // this clamping is needed since there are sometimes float point errors
00162         real low = mData.joint->getLowLimit( mData.jointAxisNum );
00163         if ( a < low )
00164         {
00165             a = low;
00166         }
00167 
00168         real high = mData.joint->getHighLimit( mData.jointAxisNum );
00169         if ( a > high )
00170         {
00171             a = high;
00172         }
00173 
00174         mData.desiredAngle = a;
00175     }
00176 
00177     void ServoMotor::setDesiredAngleNorm( real a )
00178     {
00179         if ( a < 0 )
00180             a = 0;
00181         if ( a > 1 )
00182             a = 1;
00183 
00184         real lowLimit = mData.joint->getLowLimit( mData.jointAxisNum );
00185         real highLimit = mData.joint->getHighLimit( mData.jointAxisNum );
00186 
00187         // map the pos value onto the joint limits
00188         mData.desiredAngle = a * ( highLimit - lowLimit ) + lowLimit;
00189 
00190         // Keep desired angle slightly away from the limit to avoid jitter.
00191         // @todo: fix this; this should just keep the thing away from the
00192         // limit when it's close, not all the time.
00193         mData.desiredAngle *= ( real ) 0.99;
00194     }
00195 
00196     real ServoMotor::getDesiredAngle() const
00197     {
00198         return mData.desiredAngle;
00199     }
00200 
00201     void ServoMotor::setDesiredVel( real vel )
00202     {
00203         mData.desiredVel = vel;
00204         mData.joint->internal_setDesiredVel( mData.jointAxisNum, vel );
00205     }
00206 
00207     real ServoMotor::getDesiredVel() const
00208     {
00209         return mData.desiredVel;
00210     }
00211 
00212     void ServoMotor::setMaxTorque( real max )
00213     {
00214         mData.maxTorque = max;
00215         mData.joint->internal_setMaxTorque( mData.jointAxisNum, max );
00216     }
00217 
00218     real ServoMotor::getMaxTorque() const
00219     {
00220         return mData.maxTorque;
00221     }
00222 
00223     void ServoMotor::setRestoreSpeed( real speed )
00224     {
00225         mData.restoreSpeed = speed;
00226     }
00227 
00228     real ServoMotor::getRestoreSpeed() const
00229     {
00230         return mData.restoreSpeed;
00231     }
00232 
00233     bool ServoMotor::internal_dependsOnJoint( Joint* j )
00234     {
00235         if ( j == mData.joint )
00236         {
00237             return true;
00238         }
00239         else
00240         {
00241             return false;
00242         }
00243     }
00244 }

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