phyjoint.h
1 /********************************************************************************
2  * WorldSim -- library for robot simulations *
3  * Copyright (C) 2008-2011 Gianluca Massera <emmegian@yahoo.it> *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the Free Software *
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
18  ********************************************************************************/
19 
20 #ifndef PHYJOINT_H
21 #define PHYJOINT_H
22 
23 #include "worldsimconfig.h"
24 #include "world.h"
25 #include "phyobject.h"
26 #include "wvector.h"
27 #include "wmatrix.h"
28 #include "wquaternion.h"
29 #include "ownable.h"
30 #include <QObject>
31 
32 namespace farsa {
33 
34 class PhyJoint;
35 class PhyJointPrivate;
36 class PhyObjectPrivate;
37 class WorldPrivate;
38 class Motor;
39 
50 class FARSA_WSIM_API PhyDOF : public QObject {
51  Q_OBJECT
52 public:
54  enum MotionMode { force, vel, pos, off };
55 
61  PhyDOF( PhyJoint* parent, wVector axis, wVector centre, bool translate = false ) {
62  this->ax = axis;
63  this->istranslate = translate;
64  this->centrev = centre;
65  limitsOn = false;
66  lolimit = -3.14f;
67  hilimit = +3.14f;
68  parentv = parent;
69  desiredPos = 0.0;
70  desiredVel = 0.0;
71  motionMode = pos;
72  positionv = 0.0;
73  velocityv = 0.0;
74  stiffnessv = 0.99f;
75  maxvelocityv = 1.5708f; // 90 degrees/sec
76  forcea = 0.0;
77  x_ax = wVector(0,0,0);
78  y_ax = wVector(0,0,0);
79  };
80 
82  void switchOff() {
83  motionMode = off;
84  }
85 
88  return parentv;
89  };
90 
92  const PhyJoint* joint() const {
93  return parentv;
94  };
95 
97  real appliedForce() const {
98  return forcea;
99  };
100 
102  real desiredPosition() const {
103  return desiredPos;
104  };
105 
107  real desiredVelocity() const {
108  return desiredVel;
109  };
110 
112  MotionMode motion() const {
113  return motionMode;
114  };
115 
117  void setMotionMode ( enum MotionMode m) {
118  motionMode = m;
119  }
120 
122  wVector centre() const {
123  return centrev;
124  };
126  void setCentre( const wVector& cent ) {
127  this->centrev = cent;
128  };
129 
134  real position() const {
135  return positionv;
136  };
138  void setPosition( real newpos ) {
139  positionv = newpos;
140  emit changedPosition( newpos );
141  };
142 
144  real velocity() const {
145  return velocityv;
146  };
148  void setVelocity( real newvel ) {
149  velocityv = newvel;
150  emit changedVelocity( newvel );
151  };
152 
154  void limits( real& lo, real& hi ) const {
155  lo = lolimit;
156  hi = hilimit;
157  };
158 
160  real stiffness() const {
161  return stiffnessv;
162  };
163 
165  void setStiffness( real newstiff ) {
166  //--- clamp newstiff between 0 and 0.99
167  stiffnessv = ramp( 0.0f, 0.99f, newstiff );
168  emit changedStiffness( stiffnessv );
169  };
170 
172  void setMaxVelocity( real maxvel ) {
173  maxvelocityv = maxvel;
174  };
175 
177  real maxVelocity() const {
178  return maxvelocityv;
179  };
180 
182  wVector axis() const {
183  return ax;
184  };
186  void setAxis( const wVector& ax ) {
187  this->ax = ax;
188  };
189 
191  wVector xAxis() const {
192  return x_ax;
193  };
195  void setXAxis( const wVector& x_ax ) {
196  this->x_ax = x_ax;
197  };
198 
200  wVector yAxis() const {
201  return y_ax;
202  };
204  void setYAxis( const wVector& y_ax ) {
205  this->y_ax = y_ax;
206  };
207 
209  bool translate() const {
210  return istranslate;
211  };
212 
214  bool rotate() const {
215  return !istranslate;
216  };
217 
219  bool isLimited() const {
220  return limitsOn;
221  };
222 
224  void enableLimits() {
225  limitsOn = true;
226  };
227 
229  void disableLimits() {
230  limitsOn = false;
231  };
232 public slots:
241  void applyForce( real newforce ) {
242  forcea = newforce;
243  motionMode = force;
244  emit appliedForce( newforce );
245  return;
246  };
250  void setDesiredPosition( real wishpos ) {
251  //--- change the current desired position to avoid to push to the limits
252  real offset = (fabs(hilimit)-fabs(lolimit))*0.005;
253  desiredPos = ramp( lolimit+offset, hilimit-offset, wishpos );
254  //desiredPos = wishpos;
255  motionMode = pos;
256  emit changedDesiredPosition( wishpos );
257  return;
258  };
262  void setDesiredVelocity( real wishvel ) {
263  desiredVel = wishvel;
264  motionMode = vel;
265  emit changedDesiredVelocity( wishvel );
266  return;
267  };
274  void setLimits( real lowlimit, real highlimit ) {
275 #ifdef FARSA_DEBUG
276  if ( !istranslate && lowlimit <= -PI_GRECO ) {
277  qDebug() << "DOF Lower Limit must be greater than -pi";
278  }
279  if ( !istranslate && highlimit >= PI_GRECO ) {
280  qDebug() << "DOF Higher Limit must be lesser that pi";
281  }
282 #endif
283  lolimit = lowlimit;
284  hilimit = highlimit;
285  //--- change the current desired position to avoid to push to the limits
286  real offset = (fabs(hilimit)-fabs(lolimit))*0.005;
287  desiredPos = ramp( lolimit+offset, hilimit-offset, desiredPos );
288  emit changedLimits( lolimit, hilimit );
289  };
290 
291 signals:
293  void appliedForce( real newforce );
295  void changedDesiredPosition( real wishpos );
297  void changedDesiredVelocity( real wishvel );
299  void changedPosition( real newpos );
301  void changedVelocity( real newvel );
303  void changedStiffness( real newstiff );
305  void changedLimits( real lowlimit, real highlimit );
306 private:
307  PhyJoint* parentv;
308  wVector ax;
309  wVector x_ax;
310  wVector y_ax;
311  wVector centrev;
312  bool istranslate;
313  real stiffnessv;
314  real forcea;
316  real desiredPos;
318  real desiredVel;
320  MotionMode motionMode;
323  real positionv;
325  real velocityv;
327  bool limitsOn;
329  real lolimit;
331  real hilimit;
333  real maxvelocityv;
334 };
335 
346 class FARSA_WSIM_API PhyJoint : public Ownable {
347 public:
353  PhyJoint( PhyObject* parent, PhyObject* child );
354 
356  virtual ~PhyJoint();
358  virtual PhyObject* child() {
359  return childv;
360  };
362  virtual const PhyObject* child() const {
363  return childv;
364  };
366  virtual PhyObject* parent() {
367  return parentv;
368  };
370  virtual const PhyObject* parent() const {
371  return parentv;
372  };
374  virtual unsigned int numDofs() const {
375  return dofv;
376  };
378  virtual QVector<PhyDOF*> dofs() {
379  return dofsv;
380  };
382  void enable( bool b );
384  bool isEnabled() const {
385  return enabled;
386  };
387 
389  virtual wVector centre() const = 0;
390 
393  virtual wVector getForceOnJoint() const = 0;
394 
396  virtual void updateJointInfo() = 0;
397 
400  return worldv;
401  };
402 
404  const World* world() const {
405  return worldv;
406  };
407 
412  virtual void preUpdate() {
413  /* nothing to do */
414  };
419  virtual void postUpdate() {
420  /* nothing to do */
421  };
422 
423 protected:
425  QVector<PhyDOF*> dofsv;
427  int dofv;
429  bool enabled;
436 
438  PhyJointPrivate* priv;
439  PhyObjectPrivate* parentpriv;
440  PhyObjectPrivate* childpriv;
441  WorldPrivate* worldpriv;
442  friend class PhyJointPrivate;
443  virtual void updateJoint( real timestep ) = 0;
444 };
445 
446 } // end namespace farsa
447 
448 #endif