00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef FARSA_USE_YARP_AND_ICUB
00021
00022 #ifndef PHYICUBHELPERS_H
00023 #define PHYICUBHELPERS_H
00024
00025 #include "worldsimconfig.h"
00026 #include "wvector.h"
00027 #include "wmatrix.h"
00028 #include "wquaternion.h"
00029 #include "world.h"
00030 #include "yarpobject.h"
00031 #include "wmesh.h"
00032 #include "phyhinge.h"
00033 #include "phyobject.h"
00034 #include <QVector>
00035 #include <QSet>
00036 #include <QMap>
00037 #include <QString>
00038 #include <string>
00039 #include <typeinfo>
00040
00041
00042 #ifdef __GNUC__
00043 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
00044 #pragma GCC diagnostic push
00045 #pragma GCC diagnostic ignored "-Wunused-parameter"
00046 #else
00047 #pragma GCC diagnostic ignored "-Wunused-parameter"
00048 #endif
00049 #endif
00050 #include "yarp/dev/CartesianControl.h"
00051 #include "yarp/os/ConnectionReader.h"
00052 #include "yarp/os/PortReader.h"
00053 #include "iCub/iKin/iKinHlp.h"
00054 #include "iCub/iKin/iKinSlv.h"
00055 #ifdef __GNUC__
00056 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
00057 #pragma GCC diagnostic pop
00058 #else
00059 #pragma GCC diagnostic warning "-Wunused-parameter"
00060 #endif
00061 #endif
00062
00063 namespace farsa {
00064 class PhyiCub;
00065
00073 FARSA_WSIM_API std::ostream& operator<<(std::ostream &os, const wMatrix &m);
00074
00082 FARSA_WSIM_API std::ostream& operator<<(std::ostream &os, const wVector &v);
00083
00090 FARSA_WSIM_API void convertYarpMatrixToWorldMatrix(const yarp::sig::Matrix &y, wMatrix &w);
00091
00098 FARSA_WSIM_API void convertWorldMatrixToYarpMatrix(const wMatrix &w, yarp::sig::Matrix &y);
00099
00106 class FARSA_WSIM_API DOFStatusListener : public QObject
00107 {
00108 Q_OBJECT
00109
00110 public:
00121 DOFStatusListener(const PhyDOF* dof, Qt::ConnectionType connType = Qt::DirectConnection);
00122
00126 ~DOFStatusListener();
00127
00135 void update();
00136
00142 real position() const
00143 {
00144 return m_curPosition;
00145 }
00146
00147 private slots:
00153 void setLinkAngle(real newAngle);
00154
00160 void setDesideredPosition(real desideredAngle);
00161
00168 void setDesideredVelocity(real velocity);
00169
00170 protected:
00174 const PhyDOF* const m_dof;
00175
00182 real m_curPosition;
00183
00187 real m_desideredPosition;
00188
00192 real m_velocity;
00193
00200 PhyDOF::MotionMode m_motionMode;
00201 };
00202
00229 class FARSA_WSIM_API PhyObjectsGroup : public WObject
00230 {
00231 Q_OBJECT
00232
00233 public:
00237 typedef int ChainIDType;
00238
00245 typedef int ElementIDType;
00246
00247 public:
00255 PhyObjectsGroup(PhyObject* headObject, World* world, QString name = "unamed");
00256
00260 ~PhyObjectsGroup();
00261
00270 ElementIDType addObject(PhyObject* obj, ChainIDType chainID = ChainIDType());
00271
00282 ElementIDType addJointDOF(PhyJoint* joint, unsigned int dofID, ChainIDType chainID = ChainIDType());
00283
00292 void setKinematic(bool b);
00293
00301 void setStatic(bool b);
00302
00310 void enableJoints(bool b);
00311
00318 void updateRelativePositions();
00319
00324 void resetObjectPositions()
00325 {
00326 changedMatrix();
00327 }
00328
00355 void setDOFPosition(real pos, ChainIDType chainID, ElementIDType dof);
00356
00363 void updateFromDOF();
00364
00370 virtual void preUpdate();
00371
00377 virtual void postUpdate();
00378
00384 PhyObject* getHeadObject() const
00385 {
00386 return m_headObject;
00387 }
00388
00389 private:
00396 virtual void changedMatrix();
00397
00401 PhyObject *const m_headObject;
00402
00407 struct ObjectAndMatrix
00408 {
00409 ObjectAndMatrix() :
00410 object(NULL),
00411 matrix()
00412 {
00413 }
00414
00415 ObjectAndMatrix(PhyObject* obj, wMatrix mtr) :
00416 object(obj),
00417 matrix(mtr)
00418 {
00419 }
00420
00421 PhyObject* object;
00422 wMatrix matrix;
00423 };
00424
00431 QMap<ChainIDType, QVector<ObjectAndMatrix> > m_objects;
00432
00437 struct DOFAndListener
00438 {
00439 DOFAndListener() :
00440 joint(NULL),
00441 dofID(0),
00442 listener(NULL)
00443 {
00444 }
00445
00446 DOFAndListener(PhyJoint* j, unsigned int d, DOFStatusListener* l) :
00447 joint(j),
00448 dofID(d),
00449 listener(l)
00450 {
00451 }
00452
00453 PhyJoint* joint;
00454 unsigned int dofID;
00455 DOFStatusListener* listener;
00456 };
00457
00464 QMap<ChainIDType, QVector<DOFAndListener> > m_joints;
00465 };
00466
00515 class FARSA_WSIM_API KinematicLinkInfo : public QObject
00516 {
00517 Q_OBJECT
00518
00519 public:
00529 KinematicLinkInfo();
00530
00543 KinematicLinkInfo(iCub::iKin::iKinLimb* chain, unsigned int linkID);
00544
00550 KinematicLinkInfo(const KinematicLinkInfo& other);
00551
00557 KinematicLinkInfo& operator=(const KinematicLinkInfo& other);
00558
00562 virtual ~KinematicLinkInfo();
00563
00571 void setBuddies(QSet<KinematicLinkInfo*> buddies);
00572
00580 void setWObject(WObject* wObject, const wMatrix &m = s_identityMatrix);
00581
00587 WObject* getWObject() const
00588 {
00589 return m_wObject;
00590 }
00591
00599 const wMatrix& getWObjectMatrix() const
00600 {
00601 return m_objectMatrix;
00602 }
00603
00612 const wVector& getAxis() const
00613 {
00614 return m_axis;
00615 }
00616
00625 wVector getAxisWorld() const
00626 {
00627 return m_worldTm->rotateVector(m_axis);
00628 }
00629
00641 const wVector& getBottom() const
00642 {
00643 return m_bottom;
00644 }
00645
00656 wVector getBottomWorld() const
00657 {
00658 return m_worldTm->transformVector(m_bottom);
00659 }
00660
00669 const wVector& getTop() const
00670 {
00671 return m_top;
00672 }
00673
00682 wVector getTopWorld() const
00683 {
00684 return m_worldTm->transformVector(m_top);
00685 }
00686
00694 real getHeight() const
00695 {
00696 return m_height;
00697 }
00698
00706 const wVector& getRotAxis() const
00707 {
00708 return m_rotAxis;
00709 }
00710
00718 wVector getRotAxisWObject() const
00719 {
00720 return m_objectMatrix.unrotateVector(m_rotAxis);
00721 }
00722
00732 const wVector& getRotCenter() const
00733 {
00734 return m_rotCenter;
00735 }
00736
00746 wVector getRotCenterWObject() const
00747 {
00748 return m_objectMatrix.untransformVector(m_rotCenter);
00749 }
00750
00763 void setWorldMatrix(const wMatrix *mtr);
00764
00774 const wMatrix& getWorldMatrix() const
00775 {
00776 return *m_worldTm;
00777 }
00778
00786 yarp::sig::Matrix getYarpMatrix() const
00787 {
00788 return m_chain->getH(m_linkID, true);
00789 }
00790
00799 wMatrix getYarpMatrixAswMatrix() const
00800 {
00801 wMatrix mtr;
00802 convertYarpMatrixToWorldMatrix(m_chain->getH(m_linkID, true), mtr);
00803 return mtr;
00804 }
00805
00812 const iCub::iKin::iKinLink& getiKinLink() const
00813 {
00814 return (*(m_chain->asChain()))[m_linkID];
00815 }
00816
00823 void updateInformationFromiKin();
00824
00829 void updateMatrixFromiKin();
00830
00846 void setJoint(PhyJoint *joint, bool invertedJointAxis = true, unsigned int dof = 0, bool doConnection = true, Qt::ConnectionType connType = Qt::DirectConnection);
00847
00853 PhyJoint* getJoint() const
00854 {
00855 return m_phyJoint;
00856 }
00857
00863 unsigned int getJointDOF() const
00864 {
00865 return m_phyJointDOF;
00866 }
00867
00868 public slots:
00874 void setLinkAngle(real newAngle);
00875
00881 void setDesideredPosition(real desideredAngle);
00882
00889 void setDesideredVelocity(real velocity);
00890
00897 void setiKinLinkLimits(real min, real max);
00898
00905 void updateLink();
00906
00907 private:
00917 void setWObject_NB(WObject* wObject, const wMatrix &m = s_identityMatrix);
00918
00928 void setWorldMatrix_NB(const wMatrix *mtr);
00929
00936 void updateInformationFromiKin_NB();
00937
00945 void updateMatrixFromiKin_NB();
00946
00964 void setJoint_NB(PhyJoint *joint, bool invertedJointAxis = true, unsigned int dof = 0, bool doConnection = true, Qt::ConnectionType connType = Qt::DirectConnection);
00965
00973 void setLinkAngle_NB(real newAngle);
00974
00982 void setDesideredPosition_NB(real desideredAngle);
00983
00992 void setDesideredVelocity_NB(real velocity);
00993
01002 void setiKinLinkLimits_NB(real min, real max);
01003
01010 void updateLink_NB();
01011
01018 mutable QSet<KinematicLinkInfo*> m_buddies;
01019
01031 bool m_isMasterBuddy;
01032
01036 iCub::iKin::iKinLimb* m_chain;
01037
01041 unsigned int m_linkID;
01042
01046 WObject* m_wObject;
01047
01052 wMatrix m_objectMatrix;
01053
01061 wVector m_axis;
01062
01072 wVector m_bottom;
01073
01081 wVector m_top;
01082
01089 real m_height;
01090
01095 wVector m_rotAxis;
01096
01104 wVector m_rotCenter;
01105
01113 const wMatrix* m_worldTm;
01114
01120 PhyJoint* m_phyJoint;
01121
01125 unsigned int m_phyJointDOF;
01126
01131 bool m_invertedJointAxis;
01132
01136 real m_nextAngle;
01137
01141 real m_velocity;
01142
01149 PhyDOF::MotionMode m_motionMode;
01150
01155 bool m_linkAngleUpdated;
01156
01161 static const wMatrix s_identityMatrix;
01162 };
01163
01175 template <class iKinLimb_t>
01176 class FARSA_WSIM_TEMPLATE KinematicLimb : public iKinLimb_t
01177 {
01178 public:
01182 typedef iKinLimb_t iKinLimb;
01183
01184 public:
01188 KinematicLimb() :
01189 iKinLimb(),
01190 m_links(),
01191 m_rootObject(NULL)
01192 {
01193 initLinkInfoList();
01194 }
01195
01204 KinematicLimb(const std::string &type) :
01205 iKinLimb(type),
01206 m_links(),
01207 m_rootObject(NULL)
01208 {
01209 initLinkInfoList();
01210 }
01211
01215 ~KinematicLimb()
01216 {
01217 }
01218
01226 const KinematicLinkInfo& getLinkInfo(int i) const
01227 {
01228 return m_links[i];
01229 }
01230
01238 KinematicLinkInfo& getLinkInfo(int i)
01239 {
01240 return m_links[i];
01241 }
01242
01252 void setWorldMatrix(const wMatrix *mtr)
01253 {
01254 for (int i = 0; i < m_links.size(); i++) {
01255 m_links[i].setWorldMatrix(mtr);
01256 }
01257 }
01258
01268 const wMatrix& getWorldMatrix() const
01269 {
01270 return m_links[0].getWorldMatrix();
01271 }
01272
01279 void updateInformationFromiKin()
01280 {
01281 for (int i = 0; i < m_links.size(); i++) {
01282 m_links[i].updateInformationFromiKin();
01283 }
01284 }
01285
01304 void updateMatrixFromiKin(int updateObjMatrixFromLink = 0, int updateObjMatrixUpToLink = -1)
01305 {
01306 if (updateObjMatrixFromLink < 0) {
01307 updateObjMatrixFromLink = 0;
01308 }
01309 if ((updateObjMatrixUpToLink < 0) || (updateObjMatrixUpToLink >= m_links.size())) {
01310 updateObjMatrixUpToLink = m_links.size() - 1;
01311 }
01312
01313
01314 for (int i = updateObjMatrixFromLink; i <= updateObjMatrixUpToLink; i++) {
01315 m_links[i].updateLink();
01316 }
01317
01318
01319 for (int i = updateObjMatrixFromLink; i <= updateObjMatrixUpToLink; i++) {
01320 m_links[i].updateMatrixFromiKin();
01321 }
01322 }
01323
01332 void setRootObject(WObject* rootObject)
01333 {
01334 m_rootObject = rootObject;
01335 }
01336
01342 WObject* getRootObject() const
01343 {
01344 return m_rootObject;
01345 }
01346
01370 PhyJoint* createJoint(int linkID, bool invertAxis = true, bool doConnection = true, Qt::ConnectionType connType = Qt::DirectConnection, unsigned int dof = 0)
01371 {
01372
01373 const wVector axis = invertAxis ? -getLinkInfo(linkID).getRotAxisWObject() : getLinkInfo(linkID).getRotAxisWObject();
01374 PhyObject* parent = dynamic_cast<PhyObject*>(getLinkInfo(linkID).getWObject());
01375 if (parent == NULL) {
01376
01377 PhyObjectsGroup* grp = dynamic_cast<PhyObjectsGroup*>(getLinkInfo(linkID).getWObject());
01378 if (grp != NULL) {
01379
01380 parent = grp->getHeadObject();
01381 }
01382 }
01383 WObject* const childWObject = (linkID <= 0) ? m_rootObject : getLinkInfo(linkID - 1).getWObject();
01384 PhyObject* child = dynamic_cast<PhyObject*>(childWObject);
01385 if ((child == NULL) && (typeid(childWObject) == typeid(PhyObjectsGroup*))) {
01386
01387 child = (dynamic_cast<PhyObjectsGroup*>(childWObject))->getHeadObject();
01388 }
01389
01390 Q_ASSERT_X((parent != NULL), "PhyObjectsGroup::createJoint", "This is going to crash, parent object in joint is NULL");
01391
01392
01393 PhyJoint* joint = new PhyHinge(axis, getLinkInfo(linkID).getRotCenterWObject(), parent, child);
01394 getLinkInfo(linkID).setJoint(joint, invertAxis, dof, doConnection, connType);
01395
01396 return joint;
01397 }
01398
01399 private:
01403 void initLinkInfoList()
01404 {
01405
01406 for (unsigned int i = 0; i < this->getN(); i++) {
01407 m_links.push_back(KinematicLinkInfo(this, i));
01408 this->releaseLink(i);
01409 }
01410 }
01411
01415 QVector<KinematicLinkInfo> m_links;
01416
01424 WObject *m_rootObject;
01425 };
01426 }
01427
01428 #endif
01429
01430 #endif // FARSA_USE_YARP_AND_ICUB