worldsim/include/phyjoint.h

00001 /********************************************************************************
00002  *  WorldSim -- library for robot simulations                                   *
00003  *  Copyright (C) 2008-2011 Gianluca Massera <emmegian@yahoo.it>                *
00004  *                                                                              *
00005  *  This program is free software; you can redistribute it and/or modify        *
00006  *  it under the terms of the GNU General Public License as published by        *
00007  *  the Free Software Foundation; either version 2 of the License, or           *
00008  *  (at your option) any later version.                                         *
00009  *                                                                              *
00010  *  This program is distributed in the hope that it will be useful,             *
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of              *
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               *
00013  *  GNU General Public License for more details.                                *
00014  *                                                                              *
00015  *  You should have received a copy of the GNU General Public License           *
00016  *  along with this program; if not, write to the Free Software                 *
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  *
00018  ********************************************************************************/
00019 
00020 #ifndef PHYJOINT_H
00021 #define PHYJOINT_H
00022 
00023 #include "worldsimconfig.h"
00024 #include "world.h"
00025 #include "phyobject.h"
00026 #include "wvector.h"
00027 #include "wmatrix.h"
00028 #include "wquaternion.h"
00029 #include "ownable.h"
00030 #include <QObject>
00031 
00032 namespace farsa {
00033 
00034 class PhyJoint;
00035 class PhyJointPrivate;
00036 class PhyObjectPrivate;
00037 class WorldPrivate;
00038 class Motor;
00039 
00050 class FARSA_WSIM_API PhyDOF : public QObject {
00051     Q_OBJECT
00052 public:
00054     enum MotionMode { force, vel, pos, off };
00055 
00061     PhyDOF( PhyJoint* parent, wVector axis, wVector centre, bool translate = false ) {
00062         this->ax = axis;
00063         this->istranslate = translate;
00064         this->centrev = centre;
00065         limitsOn = false;
00066         lolimit = -3.14f;
00067         hilimit = +3.14f;
00068         parentv = parent;
00069         desiredPos = 0.0;
00070         desiredVel = 0.0;
00071         motionMode = off;
00072         positionv = 0.0;
00073         velocityv = 0.0;
00074         stiffnessv = 0.99f;
00075         maxvelocityv = 1.5708f; // 90 degrees/sec
00076         forcea = 0.0;
00077         x_ax = wVector(0,0,0);
00078         y_ax = wVector(0,0,0);
00079     };
00080 
00082     PhyJoint* joint() {
00083         return parentv;
00084     };
00085 
00087     const PhyJoint* joint() const {
00088         return parentv;
00089     };
00090 
00092     real appliedForce() const {
00093         return forcea;
00094     };
00095 
00097     real desiredPosition() const {
00098         return desiredPos;
00099     };
00100 
00102     real desiredVelocity() const {
00103         return desiredVel;
00104     };
00105 
00107     MotionMode motion() const {
00108         return motionMode;
00109     };
00110 
00112     wVector centre() const {
00113         return centrev;
00114     };
00116     void setCentre( const wVector& cent ) {
00117         this->centrev = cent;
00118     };
00119 
00124     real position() const {
00125         return positionv;
00126     };
00128     void setPosition( real newpos ) {
00129         positionv = newpos;
00130         emit changedPosition( newpos );
00131     };
00132 
00134     real velocity() const {
00135         return velocityv;
00136     };
00138     void setVelocity( real newvel ) {
00139         velocityv = newvel;
00140         emit changedVelocity( newvel );
00141     };
00142 
00144     void limits( real& lo, real& hi ) const {
00145         lo = lolimit;
00146         hi = hilimit;
00147     };
00148 
00150     real stiffness() const {
00151         return stiffnessv;
00152     };
00153 
00155     void setStiffness( real newstiff ) {
00156         //--- clamp newstiff between 0 and 0.99
00157         stiffnessv = ramp( 0.0f, 0.99f, newstiff );
00158         emit changedStiffness( stiffnessv );
00159     };
00160 
00162     void setMaxVelocity( real maxvel ) {
00163         maxvelocityv = maxvel;
00164     };
00165     
00167     real maxVelocity() const {
00168         return maxvelocityv;
00169     };
00170     
00172     wVector axis() const {
00173         return ax;
00174     };
00176     void setAxis( const wVector& ax ) {
00177         this->ax = ax;
00178     };
00179 
00181     wVector xAxis() const {
00182         return x_ax;
00183     };
00185     void setXAxis( const wVector& x_ax ) {
00186         this->x_ax = x_ax;
00187     };
00188 
00190     wVector yAxis() const {
00191         return y_ax;
00192     };
00194     void setYAxis( const wVector& y_ax ) {
00195         this->y_ax = y_ax;
00196     };
00197 
00199     bool translate() const {
00200         return istranslate;
00201     };
00202 
00204     bool rotate() const {
00205         return !istranslate;
00206     };
00207 
00209     bool isLimited() const {
00210         return limitsOn;
00211     };
00212 
00214     void enableLimits() {
00215         limitsOn = true;
00216     };
00217 
00219     void disableLimits() {
00220         limitsOn = false;
00221     };
00222 public slots:
00231     void applyForce( real newforce ) {
00232         forcea = newforce;
00233         motionMode = force;
00234         emit appliedForce( newforce );
00235         return;
00236     };
00240     void setDesiredPosition( real wishpos ) {
00241         //--- change the current desired position to avoid to push to the limits
00242         real offset = (fabs(hilimit)-fabs(lolimit))*0.005;
00243         desiredPos = ramp( lolimit+offset, hilimit-offset, wishpos );
00244         //desiredPos = wishpos;
00245         motionMode = pos;
00246         emit changedDesiredPosition( wishpos );
00247         return;
00248     };
00252     void setDesiredVelocity( real wishvel ) {
00253         desiredVel = wishvel;
00254         motionMode = vel;
00255         emit changedDesiredVelocity( wishvel );
00256         return;
00257     };
00264     void setLimits( real lowlimit, real highlimit ) {
00265 #ifdef FARSA_DEBUG
00266         if ( !istranslate && lowlimit <= -PI_GRECO ) {
00267             qDebug() << "DOF Lower Limit must be greater than -pi";
00268         }
00269         if ( !istranslate && highlimit >= PI_GRECO ) {
00270             qDebug() << "DOF Higher Limit must be lesser that pi";
00271         }
00272 #endif
00273         lolimit = lowlimit;
00274         hilimit = highlimit;
00275         //--- change the current desired position to avoid to push to the limits
00276         real offset = (fabs(hilimit)-fabs(lolimit))*0.005;
00277         desiredPos = ramp( lolimit+offset, hilimit-offset, desiredPos );
00278         emit changedLimits( lolimit, hilimit );
00279     };
00280 
00281 signals:
00283     void appliedForce( real newforce );
00285     void changedDesiredPosition( real wishpos );
00287     void changedDesiredVelocity( real wishvel );
00289     void changedPosition( real newpos );
00291     void changedVelocity( real newvel );
00293     void changedStiffness( real newstiff );
00295     void changedLimits( real lowlimit, real highlimit );
00296 private:
00297     PhyJoint* parentv;
00298     wVector ax;
00299     wVector x_ax;
00300     wVector y_ax;
00301     wVector centrev;
00302     bool istranslate;
00303     real stiffnessv;
00304     real forcea;
00306     real desiredPos;
00308     real desiredVel;
00310     MotionMode motionMode;
00313     real positionv;
00315     real velocityv;
00317     bool limitsOn;
00319     real lolimit;
00321     real hilimit;
00323     real maxvelocityv;
00324 };
00325 
00336 class FARSA_WSIM_API PhyJoint : public Ownable {
00337 public:
00343     PhyJoint( PhyObject* parent, PhyObject* child );
00344 
00346     virtual ~PhyJoint();
00348     virtual PhyObject* child() {
00349         return childv;
00350     };
00352     virtual const PhyObject* child() const {
00353         return childv;
00354     };
00356     virtual PhyObject* parent() {
00357         return parentv;
00358     };
00360     virtual const PhyObject* parent() const {
00361         return parentv;
00362     };
00364     virtual unsigned int numDofs() const {
00365         return dofv;
00366     };
00368     virtual QVector<PhyDOF*> dofs() {
00369         return dofsv;
00370     };
00372     void enable( bool b );
00374     bool isEnabled() const {
00375         return enabled;
00376     };
00377     
00379     virtual wVector centre() const = 0;
00380 
00382     virtual void updateJointInfo() = 0;
00383 
00385     World* world() {
00386         return worldv;
00387     };
00388 
00390     const World* world() const {
00391         return worldv;
00392     };
00393 
00398     virtual void preUpdate() {
00399         /* nothing to do */
00400     };
00405     virtual void postUpdate() {
00406         /* nothing to do */
00407     };
00408 
00409 protected:
00411     QVector<PhyDOF*> dofsv;
00413     int dofv;
00415     bool enabled;
00417     PhyObject* parentv;
00419     PhyObject* childv;
00421     World* worldv;
00422 
00424     PhyJointPrivate* priv;
00425     PhyObjectPrivate* parentpriv;
00426     PhyObjectPrivate* childpriv;
00427     WorldPrivate* worldpriv;
00428     friend class PhyJointPrivate;
00429     virtual void updateJoint( real timestep ) = 0;
00430 };
00431 
00432 } // end namespace farsa
00433 
00434 #endif