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 #ifdef __GNUC__
00023 #warning ================================================================================================================================================================================================================= PENSARE A DIVIDERE wVector IN UNA CLASSE PER I VETTORI (QUARTO ELEMENTO = 0) E UNA PER I PUNTI (QUARTO ELEMENTO = 1) =================================================================================================================================================================================================================
00024 #endif
00025
00026 #include "phyicubhelpers.h"
00027 #include "phyicub.h"
00028 #include "phybox.h"
00029 #include "phycylinder.h"
00030 #include "physphere.h"
00031 #include "phyfixed.h"
00032 #include "phyhinge.h"
00033 #include "phyuniversal.h"
00034 #include "phycompoundobject.h"
00035 #include "motorcontrollers.h"
00036 #include "wcamera.h"
00037
00038 #ifdef __GNUC__
00039 #pragma GCC diagnostic ignored "-Wunused-parameter"
00040 #endif
00041 #include "yarp/os/ResourceFinder.h"
00042 #include "yarp/os/Bottle.h"
00043 #include "yarp/os/Property.h"
00044 #include "yarp/dev/PolyDriverList.h"
00045 #include "yarp/dev/Wrapper.h"
00046 #include "yarp/os/RateThread.h"
00047 #include "yarp/os/Network.h"
00048 #ifdef __GNUC__
00049 #pragma GCC diagnostic warning "-Wunused-parameter"
00050 #endif
00051
00052 using namespace yarp::os;
00053 using namespace yarp::dev;
00054 using namespace iCub::iKin;
00055
00056 #include <iostream>
00057
00058 namespace farsa {
00059
00060 std::ostream& operator<<(std::ostream &os, const wMatrix &m)
00061 {
00062 os.precision(3);
00063 os.setf(std::ostream::fixed);
00064 os.unsetf(std::ostream::scientific);
00065 os << std::endl
00066 << "\t" << m[0][0] << "\t" << m[0][1] << "\t" << m[0][2] << "\t" << m[0][3] << std::endl
00067 << "\t" << m[1][0] << "\t" << m[1][1] << "\t" << m[1][2] << "\t" << m[1][3] << std::endl
00068 << "\t" << m[2][0] << "\t" << m[2][1] << "\t" << m[2][2] << "\t" << m[2][3] << std::endl
00069 << "\t" << m[3][0] << "\t" << m[3][1] << "\t" << m[3][2] << "\t" << m[3][3] << std::endl;
00070
00071 return os;
00072 }
00073
00074 std::ostream& operator<<(std::ostream &os, const wVector &v)
00075 {
00076 os.precision(3);
00077 os.setf(std::ostream::fixed);
00078 os.unsetf(std::ostream::scientific);
00079 os << "[" << v.x << ", " << v.y << ", " << v.z << ", " << v.w << "]";
00080
00081 return os;
00082 }
00083
00084 void convertYarpMatrixToWorldMatrix(const yarp::sig::Matrix &y, wMatrix &w)
00085 {
00086
00087
00088 w[0][0] = y[0][0];
00089 w[0][1] = y[1][0];
00090 w[0][2] = y[2][0];
00091 w[0][3] = y[3][0];
00092 w[1][0] = y[0][1];
00093 w[1][1] = y[1][1];
00094 w[1][2] = y[2][1];
00095 w[1][3] = y[3][1];
00096 w[2][0] = y[0][2];
00097 w[2][1] = y[1][2];
00098 w[2][2] = y[2][2];
00099 w[2][3] = y[3][2];
00100 w[3][0] = y[0][3];
00101 w[3][1] = y[1][3];
00102 w[3][2] = y[2][3];
00103 w[3][3] = y[3][3];
00104 }
00105
00106 void convertWorldMatrixToYarpMatrix(const wMatrix &w, yarp::sig::Matrix &y)
00107 {
00108
00109
00110 y[0][0] = w[0][0];
00111 y[0][1] = w[1][0];
00112 y[0][2] = w[2][0];
00113 y[0][3] = w[3][0];
00114 y[1][0] = w[0][1];
00115 y[1][1] = w[1][1];
00116 y[1][2] = w[2][1];
00117 y[1][3] = w[3][1];
00118 y[2][0] = w[0][2];
00119 y[2][1] = w[1][2];
00120 y[2][2] = w[2][2];
00121 y[2][3] = w[3][2];
00122 y[3][0] = w[0][3];
00123 y[3][1] = w[1][3];
00124 y[3][2] = w[2][3];
00125 y[3][3] = w[3][3];
00126 }
00127
00128 DOFStatusListener::DOFStatusListener(const PhyDOF* dof, Qt::ConnectionType connType) :
00129 QObject(NULL),
00130 m_dof(dof),
00131 m_curPosition(dof->position()),
00132 m_desideredPosition(dof->desiredPosition()),
00133 m_velocity(dof->desiredVelocity()),
00134 m_motionMode(dof->motion())
00135 {
00136
00137 connect(m_dof, SIGNAL(changedPosition(real)), this, SLOT(setLinkAngle(real)), connType);
00138 connect(m_dof, SIGNAL(changedDesiredPosition(real)), this, SLOT(setDesideredPosition(real)), connType);
00139 connect(m_dof, SIGNAL(changedDesiredVelocity(real)), this, SLOT(setDesideredVelocity(real)), connType);
00140 }
00141
00142 DOFStatusListener::~DOFStatusListener()
00143 {
00144
00145 }
00146
00147 void DOFStatusListener::update()
00148 {
00149 switch (m_motionMode) {
00150 case PhyDOF::force:
00151 {
00152
00153 }
00154 break;
00155 case PhyDOF::vel:
00156 {
00157
00158
00159 real lowLimit, highLimit;
00160 m_dof->limits(lowLimit, highLimit);
00161 m_curPosition = ramp(lowLimit, highLimit, m_curPosition + m_velocity * m_dof->joint()->world()->timeStep());
00162 m_motionMode = PhyDOF::off;
00163 }
00164 break;
00165 case PhyDOF::pos:
00166 {
00167 m_curPosition = m_desideredPosition;
00168 m_motionMode = PhyDOF::off;
00169 }
00170 break;
00171 case PhyDOF::off:
00172 {
00173
00174 }
00175 break;
00176 }
00177 }
00178
00179 void DOFStatusListener::setLinkAngle(real newAngle)
00180 {
00181 m_curPosition = newAngle;
00182 }
00183
00184 void DOFStatusListener::setDesideredPosition(real desideredAngle)
00185 {
00186 m_desideredPosition = desideredAngle;
00187 m_motionMode = PhyDOF::pos;
00188 }
00189
00190 void DOFStatusListener::setDesideredVelocity(real velocity)
00191 {
00192 m_velocity = velocity;
00193 m_motionMode = PhyDOF::vel;
00194 }
00195
00196 PhyObjectsGroup::PhyObjectsGroup(PhyObject* headObject, World* world, QString name) :
00197 WObject(world, name),
00198 m_headObject(headObject),
00199 m_objects(),
00200 m_joints()
00201 {
00202
00203 tm = m_headObject->matrix();
00204 }
00205
00206 PhyObjectsGroup::~PhyObjectsGroup()
00207 {
00208
00209 for (QMap<ChainIDType, QVector<DOFAndListener> >::iterator it = m_joints.begin(); it != m_joints.end(); it++) {
00210 for (int i = 0; i < it.value().size(); i++) {
00211 delete it.value()[i].listener;
00212 }
00213 }
00214 }
00215
00216 PhyObjectsGroup::ElementIDType PhyObjectsGroup::addObject(PhyObject* obj, PhyObjectsGroup::ChainIDType chainID)
00217 {
00218
00219 wMatrix invHeadMatrix = m_headObject->matrix().inverse();
00220 m_objects[chainID].push_back(ObjectAndMatrix(obj, obj->matrix() * invHeadMatrix));
00221
00222 return (m_objects[chainID].size() - 1);
00223 }
00224
00225 PhyObjectsGroup::ElementIDType PhyObjectsGroup::addJointDOF(PhyJoint* joint, unsigned int dofID, PhyObjectsGroup::ChainIDType chainID)
00226 {
00227 Q_ASSERT_X(joint->numDofs() > dofID, "PhyObjectsGroup::addJointDOF", "Joint has not the given dof");
00228 m_joints[chainID].push_back(DOFAndListener(joint, dofID, new DOFStatusListener(joint->dofs()[0])));
00229
00230 return (m_joints[chainID].size() - 1);
00231 }
00232
00233 void PhyObjectsGroup::setKinematic(bool b)
00234 {
00235
00236 m_headObject->setKinematic(b);
00237 for (QMap<ChainIDType, QVector<ObjectAndMatrix> >::iterator it = m_objects.begin(); it != m_objects.end(); it++) {
00238 for (int i = 0; i < it.value().size(); i++) {
00239 it.value()[i].object->setKinematic(b);
00240 }
00241 }
00242 }
00243
00244 void PhyObjectsGroup::setStatic(bool b)
00245 {
00246
00247 m_headObject->setStatic(b);
00248 for (QMap<ChainIDType, QVector<ObjectAndMatrix> >::iterator it = m_objects.begin(); it != m_objects.end(); it++) {
00249 for (int i = 0; i < it.value().size(); i++) {
00250 it.value()[i].object->setStatic(b);
00251 }
00252 }
00253 }
00254
00255 void PhyObjectsGroup::enableJoints(bool b)
00256 {
00257
00258 for (QMap<ChainIDType, QVector<DOFAndListener> >::iterator it = m_joints.begin(); it != m_joints.end(); it++) {
00259 for (int i = 0; i < it.value().size(); i++) {
00260 it.value()[i].joint->enable(b);
00261 }
00262 }
00263 }
00264
00265 void PhyObjectsGroup::updateRelativePositions()
00266 {
00267
00268 wMatrix invHeadMatrix = m_headObject->matrix().inverse();
00269 for (QMap<ChainIDType, QVector<ObjectAndMatrix> >::iterator it = m_objects.begin(); it != m_objects.end(); it++) {
00270 for (int i = 0; i < it.value().size(); i++) {
00271 it.value()[i].matrix = it.value()[i].object->matrix() * invHeadMatrix;
00272 }
00273 }
00274 }
00275
00276 void PhyObjectsGroup::setDOFPosition(real pos, PhyObjectsGroup::ChainIDType chainID, PhyObjectsGroup::ElementIDType dof)
00277 {
00278
00279 Q_ASSERT_X(m_joints.contains(chainID), "PhyObjectsGroup::setDOFPosition", "No joint chain with the given ID");
00280 Q_ASSERT_X(m_joints[chainID].size() > dof, "PhyObjectsGroup::setDOFPosition", "No joint with the given ID in the given chain");
00281 Q_ASSERT_X(m_joints[chainID][dof].joint->dofs()[m_joints[chainID][dof].dofID]->rotate(), "PhyObjectsGroup::setDOFPosition", "Linear joints are not supported");
00282 Q_ASSERT_X(m_objects.contains(chainID), "PhyObjectsGroup::setDOFPosition", "No object chain with the given ID");
00283 Q_ASSERT_X(m_objects[chainID].size() > dof, "PhyObjectsGroup::setDOFPosition", "No object with the given ID in the given chain");
00284
00285 QVector<ObjectAndMatrix>& objChain = m_objects[chainID];
00286 QVector<DOFAndListener>& jointChain = m_joints[chainID];
00287 PhyDOF* phydof = jointChain[dof].joint->dofs()[m_joints[chainID][dof].dofID];
00288
00289
00290 for (ElementIDType i = dof; i < objChain.size(); i++) {
00291 const wMatrix newMatrixWorldCoordinate = objChain[i].object->matrix().rotateAround(-phydof->axis(), phydof->centre(), pos - phydof->position());
00292 objChain[i].matrix = newMatrixWorldCoordinate * matrix().inverse();
00293 }
00294
00295
00296
00297 for (ElementIDType i = dof; i < objChain.size(); i++) {
00298 objChain[i].object->setMatrix(objChain[i].matrix * matrix());
00299 }
00300 for (ElementIDType i = dof; i < jointChain.size(); i++) {
00301 jointChain[i].joint->updateJointInfo();
00302 }
00303 }
00304
00305 void PhyObjectsGroup::updateFromDOF()
00306 {
00307
00308
00309
00310
00311
00312 for (QMap<ChainIDType, QVector<DOFAndListener> >::iterator it = m_joints.begin(); it != m_joints.end(); it++) {
00313 for (int i = 0; i < it.value().size(); i++) {
00314 it.value()[i].listener->update();
00315 setDOFPosition(it.value()[i].listener->position(), it.key(), i);
00316 }
00317 }
00318 }
00319
00320 void PhyObjectsGroup::preUpdate()
00321 {
00322 }
00323
00324 void PhyObjectsGroup::postUpdate()
00325 {
00326 }
00327
00328 void PhyObjectsGroup::changedMatrix()
00329 {
00330
00331
00332 m_headObject->setMatrix(matrix());
00333
00334
00335 for (QMap<ChainIDType, QVector<ObjectAndMatrix> >::iterator it = m_objects.begin(); it != m_objects.end(); it++) {
00336 for (int i = 0; i < it.value().size(); i++) {
00337 it.value()[i].object->setMatrix(it.value()[i].matrix * matrix());
00338 }
00339 }
00340
00341
00342 for (QMap<ChainIDType, QVector<DOFAndListener> >::iterator it = m_joints.begin(); it != m_joints.end(); it++) {
00343 for (int i = 0; i < it.value().size(); i++) {
00344 it.value()[i].joint->updateJointInfo();
00345 }
00346 }
00347 }
00348
00349 KinematicLinkInfo::KinematicLinkInfo() :
00350 QObject(),
00351 m_buddies(),
00352 m_isMasterBuddy(true),
00353 m_chain(NULL),
00354 m_linkID(0),
00355 m_wObject(NULL),
00356 m_objectMatrix(wMatrix::identity()),
00357 m_axis(),
00358 m_bottom(),
00359 m_top(),
00360 m_height(0.0),
00361 m_worldTm(&s_identityMatrix),
00362 m_phyJoint(NULL),
00363 m_phyJointDOF(0),
00364 m_invertedJointAxis(true),
00365 m_nextAngle(0.0),
00366 m_velocity(0.0),
00367 m_motionMode(PhyDOF::off),
00368 m_linkAngleUpdated(true)
00369 {
00370 }
00371
00372 KinematicLinkInfo::KinematicLinkInfo(iCub::iKin::iKinLimb* chain, unsigned int linkID) :
00373 QObject(),
00374 m_buddies(),
00375 m_isMasterBuddy(true),
00376 m_chain(chain),
00377 m_linkID(linkID),
00378 m_wObject(NULL),
00379 m_objectMatrix(wMatrix::identity()),
00380 m_axis(),
00381 m_bottom(),
00382 m_top(),
00383 m_height(0.0),
00384 m_worldTm(&s_identityMatrix),
00385 m_phyJoint(NULL),
00386 m_phyJointDOF(0),
00387 m_invertedJointAxis(true),
00388 m_nextAngle(0.0),
00389 m_velocity(0.0),
00390 m_motionMode(PhyDOF::off),
00391 m_linkAngleUpdated(true)
00392 {
00393 updateInformationFromiKin();
00394 }
00395
00396 KinematicLinkInfo::KinematicLinkInfo(const KinematicLinkInfo& other) :
00397 QObject(),
00398 m_buddies(other.m_buddies),
00399 m_isMasterBuddy(other.m_isMasterBuddy),
00400 m_chain(other.m_chain),
00401 m_linkID(other.m_linkID),
00402 m_wObject(other.m_wObject),
00403 m_objectMatrix(other.m_objectMatrix),
00404 m_axis(other.m_axis),
00405 m_bottom(other.m_bottom),
00406 m_top(other.m_top),
00407 m_height(other.m_height),
00408 m_worldTm(other.m_worldTm),
00409 m_phyJoint(other.m_phyJoint),
00410 m_phyJointDOF(other.m_phyJointDOF),
00411 m_invertedJointAxis(other.m_invertedJointAxis),
00412 m_nextAngle(other.m_nextAngle),
00413 m_velocity(other.m_velocity),
00414 m_motionMode(other.m_motionMode),
00415 m_linkAngleUpdated(other.m_linkAngleUpdated)
00416 {
00417
00418 m_buddies.insert(const_cast<KinematicLinkInfo*>(&other));
00419 m_buddies.remove(this);
00420
00421
00422 foreach (KinematicLinkInfo* buddy, m_buddies) {
00423 buddy->m_buddies.insert(this);
00424 }
00425 }
00426
00427 KinematicLinkInfo& KinematicLinkInfo::operator=(const KinematicLinkInfo& other)
00428 {
00429 if (&other == this) {
00430 return *this;
00431 }
00432
00433 m_chain = other.m_chain;
00434 m_isMasterBuddy = other.m_isMasterBuddy;
00435 m_linkID = other.m_linkID;
00436 m_wObject = other.m_wObject;
00437 m_objectMatrix = other.m_objectMatrix;
00438 m_axis = other.m_axis;
00439 m_bottom = other.m_bottom;
00440 m_top = other.m_top;
00441 m_height = other.m_height;
00442 m_worldTm = other.m_worldTm;
00443 m_phyJoint = other.m_phyJoint;
00444 m_phyJointDOF = other.m_phyJointDOF;
00445 m_invertedJointAxis = other.m_invertedJointAxis;
00446 m_nextAngle = other.m_nextAngle;
00447 m_velocity = other.m_velocity;
00448 m_motionMode = other.m_motionMode;
00449 m_linkAngleUpdated = other.m_linkAngleUpdated;
00450
00451
00452 m_buddies = other.m_buddies;
00453
00454
00455 m_buddies.insert(const_cast<KinematicLinkInfo*>(&other));
00456 m_buddies.remove(this);
00457
00458
00459 foreach (KinematicLinkInfo* buddy, m_buddies) {
00460 buddy->m_buddies.insert(this);
00461 }
00462
00463 return *this;
00464 }
00465
00466 KinematicLinkInfo::~KinematicLinkInfo()
00467 {
00468
00469 foreach (KinematicLinkInfo* buddy, m_buddies) {
00470 buddy->m_buddies.remove(this);
00471 }
00472 }
00473
00474 void KinematicLinkInfo::setBuddies(QSet<KinematicLinkInfo*> buddies)
00475 {
00476 m_buddies = buddies;
00477 m_isMasterBuddy = true;
00478
00479
00480
00481 m_buddies.remove(this);
00482
00483
00484 foreach (KinematicLinkInfo *buddy, m_buddies) {
00485 buddy->m_buddies = m_buddies;
00486 buddy->m_isMasterBuddy = false;
00487
00488
00489 buddy->m_buddies.remove(buddy);
00490 buddy->m_buddies.insert(this);
00491
00492
00493 buddy->m_wObject = m_wObject;
00494 buddy->m_objectMatrix = m_objectMatrix;
00495 buddy->m_axis = m_axis;
00496 buddy->m_bottom = m_bottom;
00497 buddy->m_top = m_top;
00498 buddy->m_height = m_height;
00499 buddy->m_worldTm = m_worldTm;
00500 buddy->m_phyJoint = m_phyJoint;
00501 buddy->m_phyJointDOF = m_phyJointDOF;
00502 buddy->m_invertedJointAxis = m_invertedJointAxis;
00503 buddy->m_nextAngle = m_nextAngle;
00504 buddy->m_velocity = m_velocity;
00505 buddy->m_motionMode = m_motionMode;
00506 buddy->m_linkAngleUpdated = m_linkAngleUpdated;
00507 }
00508 }
00509
00510 void KinematicLinkInfo::setWObject(WObject* wObject, const wMatrix &m)
00511 {
00512
00513 setWObject_NB(wObject, m);
00514 foreach (KinematicLinkInfo *buddy, m_buddies) {
00515 buddy->setWObject_NB(wObject, m);
00516 }
00517
00518
00519 updateMatrixFromiKin();
00520 }
00521
00522 void KinematicLinkInfo::setWorldMatrix(const wMatrix *mtr)
00523 {
00524
00525 setWorldMatrix_NB(mtr);
00526 foreach (KinematicLinkInfo *buddy, m_buddies) {
00527 buddy->setWorldMatrix_NB(mtr);
00528 }
00529
00530
00531 updateMatrixFromiKin();
00532 }
00533
00534 void KinematicLinkInfo::updateInformationFromiKin()
00535 {
00536
00537 updateInformationFromiKin_NB();
00538 foreach (KinematicLinkInfo *buddy, m_buddies) {
00539 buddy->updateInformationFromiKin_NB();
00540 }
00541 }
00542
00543 void KinematicLinkInfo::updateMatrixFromiKin()
00544 {
00545
00546 updateMatrixFromiKin_NB();
00547 foreach (KinematicLinkInfo *buddy, m_buddies) {
00548 buddy->updateMatrixFromiKin_NB();
00549 }
00550 }
00551
00552 void KinematicLinkInfo::setJoint(PhyJoint *joint, bool invertedJointAxis, unsigned int dof, bool doConnection, Qt::ConnectionType connType)
00553 {
00554
00555 setJoint_NB(joint, invertedJointAxis, dof, doConnection, connType);
00556 foreach (KinematicLinkInfo *buddy, m_buddies) {
00557
00558
00559 buddy->setJoint_NB(joint, invertedJointAxis, dof, false);
00560 }
00561 }
00562
00563 void KinematicLinkInfo::setLinkAngle(real newAngle)
00564 {
00565
00566 setLinkAngle_NB(newAngle);
00567 foreach (KinematicLinkInfo *buddy, m_buddies) {
00568 buddy->setLinkAngle_NB(newAngle);
00569 }
00570 }
00571
00572 void KinematicLinkInfo::setDesideredPosition(real desideredAngle)
00573 {
00574
00575 setDesideredPosition_NB(desideredAngle);
00576 foreach (KinematicLinkInfo *buddy, m_buddies) {
00577 buddy->setDesideredPosition_NB(desideredAngle);
00578 }
00579 }
00580
00581 void KinematicLinkInfo::setDesideredVelocity(real velocity)
00582 {
00583
00584 setDesideredVelocity_NB(velocity);
00585 foreach (KinematicLinkInfo *buddy, m_buddies) {
00586 buddy->setDesideredVelocity_NB(velocity);
00587 }
00588 }
00589
00590 void KinematicLinkInfo::setiKinLinkLimits(real min, real max)
00591 {
00592
00593 setiKinLinkLimits_NB(min, max);
00594 foreach (KinematicLinkInfo *buddy, m_buddies) {
00595 buddy->setiKinLinkLimits_NB(min, max);
00596 }
00597 }
00598
00599 void KinematicLinkInfo::updateLink()
00600 {
00601
00602 updateLink_NB();
00603 foreach (KinematicLinkInfo *buddy, m_buddies) {
00604 buddy->updateLink_NB();
00605 }
00606 }
00607
00608 void KinematicLinkInfo::setWObject_NB(WObject* wObject, const wMatrix &m)
00609 {
00610 m_wObject = wObject;
00611 m_objectMatrix = m;
00612 }
00613
00614 void KinematicLinkInfo::setWorldMatrix_NB(const wMatrix *mtr)
00615 {
00616 if (mtr == NULL) {
00617 m_worldTm = &s_identityMatrix;
00618 } else {
00619 m_worldTm = mtr;
00620 }
00621 }
00622
00623 void KinematicLinkInfo::updateInformationFromiKin_NB()
00624 {
00625
00626
00627
00628 wMatrix thisMatrix;
00629 convertYarpMatrixToWorldMatrix(m_chain->getH(m_linkID, true), thisMatrix);
00630
00631
00632
00633 wMatrix prevLinkMatrix;
00634 if (m_linkID == 0) {
00635 convertYarpMatrixToWorldMatrix(m_chain->getH0(), prevLinkMatrix);
00636 } else {
00637 convertYarpMatrixToWorldMatrix(m_chain->getH(m_linkID - 1, true), prevLinkMatrix);
00638 }
00639
00640
00641 m_bottom = prevLinkMatrix.w_pos;
00642 m_top = thisMatrix.w_pos;
00643 m_axis = m_top - m_bottom;
00644 m_height = m_axis.norm();
00645 m_rotAxis = thisMatrix.unrotateVector(prevLinkMatrix.z_ax);
00646 m_rotCenter = thisMatrix.untransformVector(prevLinkMatrix.w_pos);
00647 }
00648
00649 void KinematicLinkInfo::updateMatrixFromiKin_NB()
00650 {
00651 if ((m_isMasterBuddy) && (m_wObject != NULL)) {
00652
00653 wMatrix thisMatrix;
00654 convertYarpMatrixToWorldMatrix(m_chain->getH(m_linkID, true), thisMatrix);
00655 thisMatrix = m_objectMatrix * thisMatrix * (*m_worldTm);
00656 m_wObject->setMatrix(thisMatrix);
00657 }
00658 }
00659
00660 void KinematicLinkInfo::setJoint_NB(PhyJoint *joint, bool invertedJointAxis, unsigned int dof, bool doConnection, Qt::ConnectionType connType)
00661 {
00662
00663 if (m_phyJoint != NULL) {
00664 disconnect(m_phyJoint->dofs()[m_phyJointDOF], SIGNAL(changedPosition(real)), this, SLOT(setLinkAngle(real)));
00665 disconnect(m_phyJoint->dofs()[m_phyJointDOF], SIGNAL(changedDesiredPosition(real)), this, SLOT(setDesideredPosition(real)));
00666 disconnect(m_phyJoint->dofs()[m_phyJointDOF], SIGNAL(changedDesiredVelocity(real)), this, SLOT(setDesideredVelocity(real)));
00667 disconnect(m_phyJoint->dofs()[m_phyJointDOF], SIGNAL(changedLimits(real, real)), this, SLOT(setiKinLinkLimits(real, real)));
00668 }
00669
00670 m_phyJoint = joint;
00671 m_phyJointDOF = dof;
00672 m_invertedJointAxis = invertedJointAxis;
00673
00674 if (doConnection) {
00675 connect(m_phyJoint->dofs()[m_phyJointDOF], SIGNAL(changedPosition(real)), this, SLOT(setLinkAngle(real)), connType);
00676 connect(m_phyJoint->dofs()[m_phyJointDOF], SIGNAL(changedDesiredPosition(real)), this, SLOT(setDesideredPosition(real)), connType);
00677 connect(m_phyJoint->dofs()[m_phyJointDOF], SIGNAL(changedDesiredVelocity(real)), this, SLOT(setDesideredVelocity(real)), connType);
00678 connect(m_phyJoint->dofs()[m_phyJointDOF], SIGNAL(changedLimits(real, real)), this, SLOT(setiKinLinkLimits(real, real)), connType);
00679 }
00680 }
00681
00682 void KinematicLinkInfo::setLinkAngle_NB(real newAngle)
00683 {
00684 if (!m_invertedJointAxis) {
00685 newAngle = -newAngle;
00686 }
00687 (*(m_chain->asChain()))[m_linkID].setAng(newAngle);
00688
00689 m_nextAngle = newAngle;
00690 }
00691
00692 void KinematicLinkInfo::setDesideredPosition_NB(real desideredAngle)
00693 {
00694
00695 if (m_invertedJointAxis) {
00696 m_nextAngle = desideredAngle;
00697 } else {
00698 m_nextAngle = -desideredAngle;
00699 }
00700 m_motionMode = PhyDOF::pos;
00701 m_linkAngleUpdated = false;
00702 }
00703
00704 void KinematicLinkInfo::setDesideredVelocity_NB(real velocity)
00705 {
00706
00707 if (fabs(velocity) > fabs(m_phyJoint->dofs()[m_phyJointDOF]->maxVelocity())) {
00708 velocity = (velocity > 0) ? fabs(m_phyJoint->dofs()[m_phyJointDOF]->maxVelocity()) : -fabs(m_phyJoint->dofs()[m_phyJointDOF]->maxVelocity());
00709 }
00710
00711 if (m_invertedJointAxis) {
00712 m_velocity = velocity;
00713 } else {
00714 m_velocity = -velocity;
00715 }
00716 m_motionMode = PhyDOF::vel;
00717 m_linkAngleUpdated = false;
00718 }
00719
00720 void KinematicLinkInfo::setiKinLinkLimits_NB(real min, real max)
00721 {
00722 if (m_invertedJointAxis) {
00723 (*(m_chain->asChain()))[m_linkID].setMin(min);
00724 (*(m_chain->asChain()))[m_linkID].setMax(max);
00725 } else {
00726 (*(m_chain->asChain()))[m_linkID].setMin(-max);
00727 (*(m_chain->asChain()))[m_linkID].setMax(-min);
00728 }
00729 }
00730
00731 void KinematicLinkInfo::updateLink_NB()
00732 {
00733
00734
00735 if (m_linkAngleUpdated) {
00736 return;
00737 }
00738
00739
00740 real velocity = 0.0;
00741 real position = (*(m_chain->asChain()))[m_linkID].getAng();
00742 switch (m_motionMode) {
00743 case PhyDOF::force:
00744 {
00745
00746 }
00747 break;
00748 case PhyDOF::vel:
00749 {
00750
00751
00752
00753
00754
00755 const real deltaAngle = m_velocity * m_phyJoint->world()->timeStep();
00756 velocity = m_velocity;
00757 position = (*(m_chain->asChain()))[m_linkID].getAng() + deltaAngle;
00758 if (m_invertedJointAxis) {
00759 setLinkAngle_NB(position);
00760 } else {
00761 setLinkAngle_NB(-position);
00762 }
00763 }
00764 break;
00765 case PhyDOF::pos:
00766 {
00767
00768
00769
00770
00771 velocity = (m_nextAngle - (*(m_chain->asChain()))[m_linkID].getAng()) / m_phyJoint->world()->timeStep();
00772 position = m_nextAngle;
00773 if (m_invertedJointAxis) {
00774 setLinkAngle_NB(position);
00775 } else {
00776 setLinkAngle_NB(-position);
00777 }
00778 }
00779 break;
00780 case PhyDOF::off:
00781 {
00782
00783 }
00784 break;
00785 }
00786
00787
00788 m_phyJoint->dofs()[m_phyJointDOF]->setPosition(position);
00789 m_phyJoint->dofs()[m_phyJointDOF]->setVelocity(velocity);
00790 m_linkAngleUpdated = true;
00791 }
00792
00793 const wMatrix KinematicLinkInfo::s_identityMatrix(wMatrix::identity());
00794 }
00795
00796 #endif // FARSA_USE_YARP_AND_ICUB