7#include <VirtualRobot/MathTools.h>
20 SyncCoordination::setObjPoseFromHandPoses(Eigen::Matrix4f& objPose,
21 const Eigen::Matrix4f& poseL,
22 const Eigen::Matrix4f& poseR)
31 Eigen::Matrix4f& leftPose,
32 Eigen::Matrix4f& rightPose,
89 Eigen::Matrix4f& leftPose,
94 if (leftPoseMode == PoseFrameMode::leader)
121 Eigen::Matrix4f& rightPose,
126 if (rightPoseMode == PoseFrameMode::leader)
160 if (cfg_.flagResetRt)
165 if (not cfgBufferInitialized_.load())
167 bufferNonRtCfgToRt_.reinitAllBuffers(cfg_);
168 bufferUserCfgToNonRt_.reinitAllBuffers(cfg_);
170 cfgBufferInitialized_.store(
true);
174 bufferNonRtCfgToRt_.getWriteBuffer() = cfg_;
175 bufferNonRtCfgToRt_.commitWrite();
176 bufferUserCfgToNonRt_.getWriteBuffer() = cfg_;
177 bufferUserCfgToNonRt_.commitWrite();
199 dataNonRt = bufferDataRtToNonRt_.getUpToDateReadBuffer();
200 cfgInNonRt = bufferUserCfgToNonRt_.getUpToDateReadBuffer();
206 bufferNonRtCfgToRt_.getWriteBuffer() =
cfgInNonRt;
207 bufferNonRtCfgToRt_.commitWrite();
213 bufferUserCfgToNonRt_.reinitAllBuffers(
cfgInNonRt);
218 const bool rightAsLeader,
219 const bool followerIsolation
243 if (not followerIsolation or not rightAsLeader)
245 graspMatrix.block<6, 6>(0, 0) = Eigen::MatrixXf::Identity(6, 6);
249 if (not followerIsolation or not leftAsLeader)
251 graspMatrix.block<6, 6>(0, 6) = Eigen::MatrixXf::Identity(6, 6);
258 VirtualRobot::MathTools::getPseudoInverseDamped(
graspMatrix.transpose(), lambda);
267 for (
size_t i = 0; i < 6; ++i)
269 if (stiffness(i) == 0)
275 deltaPos(i) = wrenchTarget(i) / stiffness(i);
276 if (deltaPos(i) > 0.1f)
280 else if (deltaPos(i) < -0.1f)
289 SyncCoordination::updateCurrentPose(Eigen::Matrix4f& leftPose, Eigen::Matrix4f& rightPose)
295 if (cfgInRT_.currentPose.has_value())
297 dataRt_.currentPose = cfgInRT_.currentPose.value();
301 if (cfgInRT_.leadershipMode == arondto::LeadershipMode::left_as_leader)
303 setPos(dataRt_.currentPose,
304 getPos(leftPose) +
getOri(leftPose) * dataRt_.tcp2ObjInMilliMeterL);
305 setOri(dataRt_.currentPose,
getOri(leftPose) * dataRt_.dOriInTCPL);
311 if (cfgInRT_.leadershipMode == arondto::LeadershipMode::right_as_leader)
313 setPos(dataRt_.currentPose,
314 getPos(rightPose) +
getOri(rightPose) * dataRt_.tcp2ObjInMilliMeterR);
315 setOri(dataRt_.currentPose,
getOri(rightPose) * dataRt_.dOriInTCPR);
320 setPos(dataRt_.currentPose,
321 0.5f * (
getPos(leftPose) +
getOri(leftPose) * dataRt_.tcp2ObjInMilliMeterL +
322 getPos(rightPose) +
getOri(rightPose) * dataRt_.tcp2ObjInMilliMeterR));
324 const Eigen::Matrix3f R1 = (
getOri(leftPose) * dataRt_.dOriInTCPL).topLeftCorner<3, 3>();
325 const Eigen::Matrix3f R2 = (
getOri(rightPose) * dataRt_.dOriInTCPR).topLeftCorner<3, 3>();
335 setOri(dataRt_.currentPose, q_avg.toRotationMatrix());
371 dataRt_.deltaT = deltaT;
372 cfgInRT_ = bufferNonRtCfgToRt_.getUpToDateReadBuffer();
374 auto& iL = input.at(cfgInRT_.nodesetLeft);
375 auto& iR = input.at(cfgInRT_.nodesetRight);
380 if (not cfgInRT_.flagResetRt)
386 dataRt_.reset(cfgInRT_.desiredPose,
396 const bool leftAsLeader =
397 cfgInRT_.leadershipMode == arondto::LeadershipMode::left_as_leader;
398 const bool rightAsLeader =
399 cfgInRT_.leadershipMode == arondto::LeadershipMode::right_as_leader;
402 dataRt_.resetGraspVariableLeft(cfgInRT_.desiredPose, iL.targetPose, iL.targetPoseMode);
406 dataRt_.resetGraspVariableRight(cfgInRT_.desiredPose, iR.targetPose, iR.targetPoseMode);
408 dataRt_.updateGraspMatrix(leftAsLeader,
410 cfgInRT_.followerConnectionMode ==
411 arondto::ConnectionMode::follower_isolated);
415 bufferDataRtToNonRt_.reinitAllBuffers(dataRt_);
422 updateCurrentPose(iL.pose, iR.pose);
426 dataRt_.bimanualVel << iL.vel, iR.vel;
427 dataRt_.currentVel = dataRt_.pinvGraspMatrixT * dataRt_.bimanualVel;
429 dataRt_.bimanualFT << iL.ft, iR.ft;
431 dataRt_.currentFT = dataRt_.graspMatrix * dataRt_.bimanualFT;
432 for (
size_t i = 0; i < 6; i++)
434 if (fabs(dataRt_.currentFT(i)) < cfg_.forceDeadzone(i))
436 dataRt_.currentFT(i) = 0.0f;
440 dataRt_.currentFT(i) -=
441 cfg_.forceDeadzone(i) * dataRt_.currentFT(i) / fabs(dataRt_.currentFT(i));
445 computeWrenchControl(
446 dataRt_.deltaPosForWrenchControlL, cfg_.targetWrenchLeft, iL.stiffness);
447 computeWrenchControl(
448 dataRt_.deltaPosForWrenchControlR, cfg_.targetWrenchRight, iR.stiffness);
451 dataRt_.targetPose = cfgInRT_.desiredPose;
452 dataRt_.poseError.head<3>() =
getPos(dataRt_.virtualPose) -
getPos(dataRt_.targetPose);
453 dataRt_.oriError =
getOri(dataRt_.virtualPose) *
getOriT(dataRt_.targetPose);
454 dataRt_.poseError.tail<3>() = VirtualRobot::MathTools::eigen3f2rpy(dataRt_.oriError);
456 for (
int i = 0; i < 6; i++)
458 dataRt_.tempAcc(i) = dataRt_.currentFT(i) / cfg_.virtualInertia(i) -
459 cfg_.virtualStiffness(i) * dataRt_.poseError(i) -
460 cfg_.virtualDamping(i) * dataRt_.virtualVel(i);
465 dataRt_.tempVel = dataRt_.virtualVel + 0.5f *
static_cast<float>(deltaT) *
466 (dataRt_.tempAcc + dataRt_.virtualAcc);
469 0.5f *
static_cast<float>(deltaT) * (dataRt_.virtualVel + dataRt_.tempVel);
471 dataRt_.virtualVel = dataRt_.tempVel;
472 dataRt_.virtualAcc = dataRt_.tempAcc;
473 setOri(dataRt_.virtualPose,
474 VirtualRobot::MathTools::rpy2eigen3f(
475 dataRt_.poseError(3), dataRt_.poseError(4), dataRt_.poseError(5)) *
476 getOri(dataRt_.virtualPose));
477 setPos(dataRt_.virtualPose,
getPos(dataRt_.virtualPose) + dataRt_.poseError.head<3>());
480 setOri(iL.targetPose,
getOri(dataRt_.virtualPose) * dataRt_.dOriInObjL);
481 setOri(iR.targetPose,
getOri(dataRt_.virtualPose) * dataRt_.dOriInObjR);
483 getPos(dataRt_.virtualPose) +
484 getOri(dataRt_.virtualPose) * (1000.0f * dataRt_.obj2TcpInMeterL -
485 dataRt_.deltaPosForWrenchControlL.head<3>()));
487 getPos(dataRt_.virtualPose) +
488 getOri(dataRt_.virtualPose) * (1000.0f * dataRt_.obj2TcpInMeterR -
489 dataRt_.deltaPosForWrenchControlR.head<3>()));
491 bufferDataRtToNonRt_.getWriteBuffer() = dataRt_;
492 bufferDataRtToNonRt_.commitWrite();
499 const bool flagResetRt)
511 if (cfg_.leadershipMode == arondto::LeadershipMode::object_as_leader and
512 cfg_.followerConnectionMode == arondto::ConnectionMode::follower_isolated)
514 ARMARX_WARNING <<
"When both arms are follower, you cannot set follower isolation "
515 "flag. I changed to `ConnectionMode::follower_connected` for you";
516 cfg_.followerConnectionMode = arondto::ConnectionMode::follower_connected;
520 cfg_.flagResetRt = flagResetRt;
522 if (cfg_.flagResetRt)
528 if (cfg_.currentPose.has_value())
531 if (cfg_.currentPose.value()(3, 3) < 1.0)
533 cfg_.currentPose.reset();
536 <<
VAROUT(cfg_.currentPose.has_value());
540 ARMARX_INFO <<
"User does not provide a current pose";
553 if (not cfgBufferInitialized_.load())
555 bufferNonRtCfgToRt_.reinitAllBuffers(cfg_);
556 bufferUserCfgToNonRt_.reinitAllBuffers(cfg_);
558 cfgBufferInitialized_.store(
true);
562 bufferNonRtCfgToRt_.getWriteBuffer() = cfg_;
563 bufferNonRtCfgToRt_.commitWrite();
564 bufferUserCfgToNonRt_.getWriteBuffer() = cfg_;
565 bufferUserCfgToNonRt_.commitWrite();
572 if (cfg_.leadershipMode == arondto::LeadershipMode::left_as_leader)
574 role = cfg_.nodesetLeft +
" as leader";
576 else if (cfg_.leadershipMode == arondto::LeadershipMode::right_as_leader)
578 role = cfg_.nodesetRight +
" as leader";
582 role =
"object as leader";
586 if (cfg_.followerFrameMode == armarx::control::common::arondto::PoseFrameMode::leader)
588 role +=
", follower in local frame of leader";
590 ARMARX_INFO <<
"Request coordinator with " << role;
596 cfg_.desiredPose = targetPose;
597 bufferUserCfgToNonRt_.getWriteBuffer() = cfg_;
598 bufferUserCfgToNonRt_.commitWrite();
std::atomic_bool initialized_
void setNodesetList(const std::string &nodesetLeft, const std::string &nodesetRight)
void reset(std::map< std::string, Eigen::Matrix4f > &initPose) override
SyncCoordination(const ::armarx::aron::data::dto::DictPtr &dto)
void runRT(std::map< std::string, InputData > &input, double deltaT) override
void resetBufferUserCfgAfterMP()
std::recursive_mutex mtx_data_non_rt
TODO private?
TripleBuffer< Data > bufferDataRtToPublish
void updateNonRt() override
void rtPreActivate() final
void updateTargetPose(const Eigen::Matrix4f &targetPose)
void updateConfig(const ::armarx::aron::data::dto::DictPtr &dto, bool flagResetRt=false) override
TripleBuffer< Config > bufferUserCfgToPublish
void commitNonRt() override
#define ARMARX_INFO
The normal logging level.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Quaternion< float, 0 > Quaternionf
Matrix< float, 6, 1 > Vector6f
This file is part of ArmarX.
armarx::control::common::arondto::PoseFrameMode PoseFrameMode
Eigen::Matrix3f getOriT(const Eigen::Matrix4f &matrix)
void setOri(Eigen::Matrix4f &matrix, const Eigen::Ref< const Eigen::Matrix3f > &ori)
Eigen::Block< Eigen::Matrix4f, 3, 3 > getOri(Eigen::Matrix4f &matrix)
void setPos(Eigen::Matrix4f &matrix, const Eigen::Ref< const Eigen::Vector3f > &pos)
void skew(const Eigen::Vector3f &vec, Eigen::Ref< Eigen::Matrix3f > result)
Eigen::Block< Eigen::Matrix4f, 3, 1 > getPos(Eigen::Matrix4f &matrix)
Eigen::VectorXf bimanualVel
Eigen::Vector6f virtualAcc
Eigen::Matrix4f virtualPose
Eigen::Vector3f tcp2ObjInMilliMeterR
void updateGraspMatrix(const bool leftAsLeader, const bool rightAsLeader, const bool followerIsolation)
Eigen::Vector6f deltaPosForWrenchControlR
Eigen::Vector6f deltaObjPose
Eigen::Matrix4f currentPose
Eigen::Matrix3f dOriInObjL
void resetGraspVariableLeft(const Eigen::Matrix4f &desiredPose, Eigen::Matrix4f &leftPose, PoseFrameMode leftPoseMode)
Eigen::Vector3f obj2TcpInMeterR
Eigen::MatrixXf graspMatrix
Eigen::MatrixXf pinvGraspMatrixT
Eigen::Vector6f deltaPosForWrenchControlL
Eigen::Vector6f currentVel
Eigen::Vector3f rvec
Temporal variables to avoid memory allocation.
Eigen::Vector6f currentFT
void reset(const Eigen::Matrix4f &desiredPose, Eigen::Matrix4f &leftPose, Eigen::Matrix4f &rightPose, PoseFrameMode leftPoseMode, PoseFrameMode rightPoseMode)
Eigen::Matrix3f dOriInTCPR
Eigen::Vector6f poseError
Eigen::Vector3f tcp2ObjInMilliMeterL
Eigen::Matrix4f targetPose
void resetGraspVariableRight(const Eigen::Matrix4f &desiredPose, Eigen::Matrix4f &rightPose, PoseFrameMode rightPoseMode)
Eigen::VectorXf bimanualFT
Eigen::Matrix3f dOriInTCPL
Eigen::Vector3f obj2TcpInMeterL
vectors represented in the object local frame
Eigen::Matrix3f dOriInObjR
Eigen::Vector6f virtualVel