diff --git a/interface/slice/units/TCPControlUnit.ice b/interface/slice/units/TCPControlUnit.ice index b35bb035f312bfb555b589c0543a2cfed0309d40..6b7517f5f42fbe41cb08266ce4b053d859a38438 100644 --- a/interface/slice/units/TCPControlUnit.ice +++ b/interface/slice/units/TCPControlUnit.ice @@ -30,6 +30,7 @@ #include <observers/VariantBase.ice> #include <observers/ObserverInterface.ice> #include <robotstate/RobotState.ice> +#include <robotstate/PoseBase.ice> module armarx { @@ -37,11 +38,25 @@ module armarx interface TCPControlUnitInterface extends armarx::SensorActorUnitInterface { void setCycleTime(int milliseconds); - void setTCPVelocity(string tcpNodeName, FramedVector3Base translationVelocity, FramedVector3Base orientationVelocityRPY); +// void setTCPVelocity(string robotNodeSetName, FramedVector3Base translationVelocity, FramedVector3Base orientationVelocityRPY); + void setTCPVelocity(string robotNodeSetName, string tcpNodeName, FramedVector3Base translationVelocity, FramedVector3Base orientationVelocityRPY); }; + dictionary<string, FramedPoseBase> FramedPoseBaseMap; + interface TCPControlUnitListener + { + void reportTCPPose(FramedPoseBaseMap tcpPoses); + void reportTCPVelocities(FramedVector3Map tcpTranslationVelocities, FramedVector3Map tcpOrienationVelocities); + + }; + + interface TCPControlUnitObserverInterface extends ObserverInterface, TCPControlUnitListener + { + + }; + }; diff --git a/source/RobotAPI/applications/TCPControlUnit/TCPControlUnitApp.h b/source/RobotAPI/applications/TCPControlUnit/TCPControlUnitApp.h index 7aa35ef134e9537ab660d3820a04a3d6e30b33b8..4ab7d2dee5cd1843c729a4ea0f3ab2571b6cf801 100755 --- a/source/RobotAPI/applications/TCPControlUnit/TCPControlUnitApp.h +++ b/source/RobotAPI/applications/TCPControlUnit/TCPControlUnitApp.h @@ -24,6 +24,7 @@ #include <Core/core/application/Application.h> #include <RobotAPI/units/TCPControlUnit.h> +#include <RobotAPI/units/TCPControlUnitObserver.h> namespace armarx { @@ -33,6 +34,7 @@ namespace armarx void setup(const ManagedIceObjectRegistryInterfacePtr& registry, Ice::PropertiesPtr properties) { registry->addObject( Component::create<TCPControlUnit>(properties) ); + registry->addObject( Component::create<TCPControlUnitObserver>(properties) ); } }; } diff --git a/source/RobotAPI/units/CMakeLists.txt b/source/RobotAPI/units/CMakeLists.txt index c5a957fdda25a6e960718e6755f4023c51be57e5..50c02b62cac78eb3aeb48e831c13cda9125baf48 100755 --- a/source/RobotAPI/units/CMakeLists.txt +++ b/source/RobotAPI/units/CMakeLists.txt @@ -17,13 +17,16 @@ if (ARMARX_BUILD) set(LIBS RobotAPIInterfaces RobotAPICore ArmarXInterfaces ArmarXCore ArmarXCoreObservers ArmarXCoreRemoteRobot ${VirtualRobot_LIBRARIES}) - set(LIB_FILES + set(LIB_HEADERS ForceTorqueObserver.h TCPControlUnit.h + TCPControlUnitObserver.h + ) - set(LIB_HEADERS + set(LIB_FILES ForceTorqueObserver.cpp TCPControlUnit.cpp + TCPControlUnitObserver.cpp ) diff --git a/source/RobotAPI/units/ForceTorqueObserver.cpp b/source/RobotAPI/units/ForceTorqueObserver.cpp index d5db0ce9fa9a0e2e14ee41896f7bd1fb1c7c391e..dd43ebb29a7ad5e331d6aed852f6e672f196bbbc 100644 --- a/source/RobotAPI/units/ForceTorqueObserver.cpp +++ b/source/RobotAPI/units/ForceTorqueObserver.cpp @@ -25,7 +25,7 @@ ForceTorqueObserver::ForceTorqueObserver() void ForceTorqueObserver::onInitObserver() { - usingTopic(getProperty<std::string>("ForceTorqueUnitName").getValue() + "State"); + usingTopic(getProperty<std::string>("ForceTorqueTopicName").getValue()); // register all checks offerConditionCheck("updated", new ConditionCheckUpdated()); diff --git a/source/RobotAPI/units/ForceTorqueObserver.h b/source/RobotAPI/units/ForceTorqueObserver.h index 59d453b4bd2c9380ed2907a0dd59478ae2ed9557..8b9c34dc2276e7f88c74577ed65fbbaebd62e450 100644 --- a/source/RobotAPI/units/ForceTorqueObserver.h +++ b/source/RobotAPI/units/ForceTorqueObserver.h @@ -14,7 +14,7 @@ namespace armarx ForceTorqueObserverPropertyDefinitions(std::string prefix): ComponentPropertyDefinitions(prefix) { - defineRequiredProperty<std::string>("ForceTorqueUnitName","Name of the ForceTorqueUnit"); + defineRequiredProperty<std::string>("ForceTorqueTopicName","Name of the ForceTorqueUnit Topic"); } }; diff --git a/source/RobotAPI/units/TCPControlUnit.cpp b/source/RobotAPI/units/TCPControlUnit.cpp index 687f352d40ef074ee68ab4088c17f549c8ba56dd..5f0123486f1bf598a746cbcd66397d93828eee71 100644 --- a/source/RobotAPI/units/TCPControlUnit.cpp +++ b/source/RobotAPI/units/TCPControlUnit.cpp @@ -32,6 +32,7 @@ #include <VirtualRobot/RobotConfig.h> #include <VirtualRobot/XML/RobotIO.h> +using namespace VirtualRobot; @@ -49,6 +50,7 @@ namespace armarx { usingProxy(getProperty<std::string>("KinematicUnitName").getValue()); usingProxy("RobotStateComponent"); + offeringTopic("TCPControlUnitState"); } @@ -91,10 +93,16 @@ namespace armarx // setTCPVelocity("RightLeg", tcpVel, NULL); // setTCPVelocity("LeftLeg", tcpVel, NULL); // request(); + + listener = getTopic<TCPControlUnitListenerPrx>("TCPControlUnitState"); + topicTask = new PeriodicTask<TCPControlUnit>(this, &TCPControlUnit::periodicReport,cycleTime, false, "TCPDataProvider"); + topicTask->start(); } void TCPControlUnit::onDisconnectComponent() { + if(topicTask) + topicTask->stop(); release(); } @@ -112,14 +120,26 @@ namespace armarx execTask->changeInterval(cycleTime); } - void TCPControlUnit::setTCPVelocity(const std::string &tcpNodeName, const FramedVector3BasePtr &translationVelocity, const FramedVector3BasePtr &orientationVelocityRPY, const Ice::Current &c) + void TCPControlUnit::setTCPVelocity(const std::string &nodeSetName, const std::string &tcpName, const FramedVector3BasePtr &translationVelocity, const FramedVector3BasePtr &orientationVelocityRPY, const Ice::Current &c) { ScopedLock lock(dataMutex); - ARMARX_VERBOSE << "Setting new Velocity\n" << FramedVector3Ptr::dynamicCast(translationVelocity)->toEigen(); if(translationVelocity) - targetTranslationVelocities[tcpNodeName] = translationVelocity; + ARMARX_VERBOSE << "Setting new Velocity for " << nodeSetName << "\n" << FramedVector3Ptr::dynamicCast(translationVelocity)->toEigen(); if(orientationVelocityRPY) - targetOrientationVelocitiesRPY[tcpNodeName] = orientationVelocityRPY; + ARMARX_VERBOSE << "Orientation Velo: " << FramedVector3Ptr::dynamicCast(orientationVelocityRPY)->toEigen(); + TCPVelocityData data; + data.nodeSetName = nodeSetName; + data.translationVelocity = FramedVector3Ptr::dynamicCast(translationVelocity); + data.orientationVelocity = FramedVector3Ptr::dynamicCast(orientationVelocityRPY); + if(tcpName.empty()) + data.tcpName = localRobot->getRobotNodeSet(nodeSetName)->getTCP()->getName(); + else + data.tcpName = tcpName; + tcpVelocitiesMap[data.tcpName] = data; +// if(translationVelocity) +// targetTranslationVelocities[nodeSetName] = translationVelocity; +// if(orientationVelocityRPY) +// targetOrientationVelocitiesRPY[nodeSetName] = orientationVelocityRPY; } @@ -161,8 +181,11 @@ namespace armarx cycleTime = this->cycleTime; } ARMARX_IMPORTANT << "Requesting TCPControlUnit"; + if(execTask) + execTask->stop(); execTask = new PeriodicTask<TCPControlUnit>(this, &TCPControlUnit::periodicExec, cycleTime, true, "TCPVelocityCalculator"); execTask->start(); + ARMARX_IMPORTANT << "Requested TCPControlUnit"; } void TCPControlUnit::release(const Ice::Current & c) @@ -172,165 +195,174 @@ namespace armarx if(execTask) execTask->stop(); kinematicUnitPrx->stop(); + ARMARX_IMPORTANT << "Released TCPControlUnit"; + } void TCPControlUnit::periodicExec() { + ARMARX_INFO << deactivateSpam(4) << "periodicExec for " << tcpVelocitiesMap.size(); // IceUtil::Time startTime = IceUtil::Time::now(); ScopedLock lock(dataMutex); -// std::stringstream time; -// time << IceUtil::Time::now().toMicroSeconds(); - // VirtualRobot::RobotPtr remoteRobot; - // remoteRobot.reset( new RemoteRobot(robotStateComponentPrx->getRobotSnapshot(time.str()))); - // remoteRobot->setUpdateVisualization(false); - // remoteRobot->setThreadsafe(false); + NameValueMap robotConfigMap = remoteRobotPrx->getConfig(); - NameValueMap::iterator it = robotConfigMap.begin(); +// NameValueMap::iterator it = robotConfigMap.begin(); std::map<std::string, float> jointValues(robotConfigMap.begin(), robotConfigMap.end()); -// std::vector<std::string> nodeNames; -// std::vector<float> nodeValues; -// for(; it != robotConfigMap.end(); it++) -// { -// std::string name = it->first; -// if(name.find("LeftArm") != std::string::npos) -// ARMARX_INFO << "New Values: " << it->first << " is " << it->second; -// nodeNames.push_back(it->first); -// nodeValues.push_back(it->second); -// localRobot->getRobotNode(it->first)->setJointValue(it->second); -// ARMARX_INFO << "New Values: " << it->first << " is " << localRobot->getRobotNode(it->first)->getJointValue(); -// } -// VirtualRobot::RobotConfigPtr robotConfig(new VirtualRobot::RobotConfig(localRobot, "localRobot", nodeNames, nodeValues)); -// if(!robotConfig->setJointValues()) -// throw LocalException("Could not update local robot joint values"); + localRobot->setJointValues(jointValues); - // ARMARX_IMPORTANT << "LeftArm_Joint3: " << localRobot->getRobotNode("LeftArm_Joint3")->getJointValue(); - FramedVector3Map::const_iterator itTrans = targetTranslationVelocities.begin(); - for(; itTrans != targetTranslationVelocities.end(); itTrans++) +// dIKMap.clear(); + TCPVelocityDataMap::iterator it = tcpVelocitiesMap.begin(); + for(; it != tcpVelocitiesMap.end(); it++) { + const TCPVelocityData& data = it->second; + RobotNodeSetPtr nodeSet = localRobot->getRobotNodeSet(data.nodeSetName); + std::string refFrame = nodeSet->getTCP()->getName(); + DIKMap::iterator itDIK = dIKMap.find(data.nodeSetName); + if(itDIK == dIKMap.end()) + dIKMap[data.nodeSetName].reset(new EDifferentialIK(nodeSet, localRobot->getRootNode()/*, VirtualRobot::JacobiProvider::eTranspose*/)); + boost::shared_dynamic_cast<EDifferentialIK>(dIKMap[data.nodeSetName])->clearGoals(); + } - Eigen::VectorXf jointDelta; + using namespace Eigen; - FramedVector3Ptr targetTranslationVelocity = FramedVector3Ptr::dynamicCast(itTrans->second); - if(targetTranslationVelocity->getFrame() == "") - continue; - VirtualRobot::RobotNodeSetPtr robotNodeSet = localRobot->getRobotNodeSet(itTrans->first); - std::string refFrame = targetTranslationVelocity->getFrame(); + it = tcpVelocitiesMap.begin(); + for(; it != tcpVelocitiesMap.end(); it++) + { + TCPVelocityData& data = it->second; + RobotNodeSetPtr nodeSet = localRobot->getRobotNodeSet(data.nodeSetName); + std::string refFrame = localRobot->getRootNode()->getName(); - FramedVector3Map::const_iterator itOri = targetOrientationVelocitiesRPY.find(itTrans->first); - if(itOri != targetOrientationVelocitiesRPY.end() && itOri->second) + IKSolver::CartesianSelection mode; + if(data.translationVelocity && data.orientationVelocity) { - FramedVector3Ptr targetOrientationVelocitiesRPY = FramedVector3Ptr::dynamicCast(itOri->second);; - if(targetOrientationVelocitiesRPY->getFrame() == "") - continue; - - -// if(targetTranslationVelocity->toEigen().norm() == 0 -// && targetOrientationVelocitiesRPY->toEigen().norm() == 0) -// continue; + mode = IKSolver::All; +// ARMARX_INFO << deactivateSpam(4) << "FullMode"; + } + else if(data.translationVelocity && !data.orientationVelocity) + mode = IKSolver::Position; + else if(!data.translationVelocity && data.orientationVelocity) + mode = IKSolver::Orientation; + else + { +// ARMARX_VERBOSE << deactivateSpam(2) << "No mode feasible for " << data.nodeSetName << " - skipping"; + continue; + } + RobotNodePtr tcpNode = localRobot->getRobotNode(data.tcpName); + Eigen::Matrix4f m; + m.setIdentity(); + if(data.orientationVelocity) + { + data.orientationVelocity = FramedVector3::ChangeFrame(localRobot, *data.orientationVelocity, refFrame); +// ARMARX_INFO << deactivateSpam(1) << "Orientation in " << refFrame << ": " << data.orientationVelocity->toEigen(); + Eigen::Matrix3f rot; + rot = Eigen::AngleAxisf(data.orientationVelocity->z, Eigen::Vector3f::UnitZ()) + * Eigen::AngleAxisf(data.orientationVelocity->y, Eigen::Vector3f::UnitY()) + * Eigen::AngleAxisf(data.orientationVelocity->x, Eigen::Vector3f::UnitX()); + m.block(0,0,3,3) = rot * tcpNode->getGlobalPose().block(0,0,3,3); + } +// ARMARX_VERBOSE << deactivateSpam(1) << "Delta Mat: \n" << m; - FramedVector3Ptr lVecTrans = FramedVector3::ChangeFrame(localRobot, *targetTranslationVelocity, refFrame); - FramedVector3Ptr lVecOri = FramedVector3::ChangeFrame(localRobot, *targetOrientationVelocitiesRPY, refFrame); - Eigen::VectorXf tcpDelta(6); - tcpDelta.head(3) = lVecTrans->toEigen(); - tcpDelta.tail(3) = lVecOri->toEigen(); - jointDelta = calcJointVelocities(robotNodeSet, tcpDelta, localRobot->getRobotNode(refFrame), VirtualRobot::IKSolver::All); +// m = m * tcpNode->getGlobalPose(); - // for (int r = 0; r < jointDelta.rows(); ++r) { - // if(jointDelta(r) > maxJointVelocity) - // { - // - // break; - // } - // } + if(data.translationVelocity) + { + data.translationVelocity = FramedVector3::ChangeFrame(localRobot, *data.translationVelocity, refFrame); +// ARMARX_INFO << deactivateSpam(1) << "Translation in " << refFrame << ": " << data.translationVelocity->toEigen(); + m.block(0,3,3,1) = tcpNode->getGlobalPose().block(0,3,3,1) + data.translationVelocity->toEigen(); + } - } - else // only position control + DifferentialIKPtr dIK = dIKMap[data.nodeSetName]; + if(!dIK) { -// if(targetTranslationVelocity->toEigen().norm() == 0) -// continue; + ARMARX_WARNING << deactivateSpam(1) << "DiffIK is NULL for robot node set: " << data.nodeSetName; + continue; + } +// ARMARX_VERBOSE << deactivateSpam(1) << "Old Pos: \n" << tcpNode->getGlobalPose(); +// ARMARX_VERBOSE << deactivateSpam(1) << "New Goal: \n" << m; + dIK->setGoal(m, tcpNode,mode); - FramedVector3Ptr lVecTrans = FramedVector3::ChangeFrame(localRobot, *targetTranslationVelocity, refFrame); +// ARMARX_VERBOSE << deactivateSpam(1) << "Delta to Goal: " << dIK->getDeltaToGoal(tcpNode); + } - Eigen::VectorXf tcpDelta(3); - tcpDelta = lVecTrans->toEigen(); - jointDelta = calcJointVelocities(robotNodeSet, tcpDelta, localRobot->getRobotNode(refFrame), VirtualRobot::IKSolver::Position); + NameValueMap targetVelocities; + NameControlModeMap controlModes; + DIKMap::iterator itDIK = dIKMap.begin(); + for(; itDIK != dIKMap.end(); itDIK++) + { + RobotNodeSetPtr robotNodeSet = localRobot->getRobotNodeSet(itDIK->first); + EDifferentialIKPtr dIK = boost::shared_dynamic_cast<EDifferentialIK>(itDIK->second); + Eigen::VectorXf jointDelta = dIK->computeStep(1.0); - } + MatrixXf fullJac = dIK->calcFullJacobian(); + MatrixXf fullJacInv = dIK->computePseudoInverseJacobianMatrix(fullJac); + Eigen::VectorXf jointLimitCompensation = CalcJointLimitAvoidanceDeltas(robotNodeSet,fullJac, fullJacInv); + jointDelta += jointLimitCompensation; - jointDelta = applyMaxJointVelocity(jointDelta,this->maxJointVelocity); + jointDelta = applyMaxJointVelocity(jointDelta, maxJointVelocity); Eigen::Vector3f currentTCPPosition = robotNodeSet->getTCP()->getGlobalPose().block(0,3,3,1); -// ARMARX_INFO << "Current TCP Position: \n" << currentTCPPosition; - ARMARX_DEBUG << deactivateSpam(2)<< "ActualTCPVelocity: " << (currentTCPPosition - lastTCPPose.block(0,3,3,1))/(0.001*cycleTime); + // ARMARX_INFO << "Current TCP Position: \n" << currentTCPPosition; + ARMARX_VERBOSE << deactivateSpam(2)<< "ActualTCPVelocity: " << (currentTCPPosition - lastTCPPose.block(0,3,3,1))/(0.001*cycleTime); lastTCPPose = robotNodeSet->getTCP()->getGlobalPose(); // build name value map - NameValueMap targetVelocities; - NameControlModeMap controlModes; + const std::vector< VirtualRobot::RobotNodePtr > nodes = robotNodeSet->getAllRobotNodes(); std::vector< VirtualRobot::RobotNodePtr >::const_iterator iter = nodes.begin(); int i = 0; while (iter != nodes.end() && i < jointDelta.rows()) { + if(targetVelocities.find((*iter)->getName()) != targetVelocities.end()) + ARMARX_WARNING << deactivateSpam(2) << (*iter)->getName() << " is set from two joint delta calculations - overwriting first value"; targetVelocities.insert(std::make_pair((*iter)->getName(), jointDelta(i))); controlModes.insert(std::make_pair((*iter)->getName(), eVelocityControl)); i++; iter++; }; - - // execute velocities - kinematicUnitPrx->switchControlMode(controlModes); - kinematicUnitPrx->setJointVelocities(targetVelocities); - } -// ARMARX_INFO << "Compensation (usec): " << (IceUtil::Time::now() - startTime).toMicroSecondsDouble(); - - } - Eigen::VectorXf TCPControlUnit::calcJointVelocities(VirtualRobot::RobotNodeSetPtr robotNodeSet, Eigen::VectorXf tcpDelta, VirtualRobot::RobotNodePtr refFrame, VirtualRobot::IKSolver::CartesianSelection mode) - { -// IceUtil::Time startCreation = IceUtil::Time::now(); - // TODO: Turn into member variable! - VirtualRobot::DifferentialIKPtr dIK(new VirtualRobot::DifferentialIK(robotNodeSet, refFrame/*, VirtualRobot::JacobiProvider::eTranspose*/)); - VirtualRobot::RobotNodePtr tcpNode = robotNodeSet->getTCP(); -// ARMARX_INFO << "creation: " << (IceUtil::Time::now() - startCreation).toMicroSecondsDouble(); + kinematicUnitPrx->switchControlMode(controlModes); + kinematicUnitPrx->setJointVelocities(targetVelocities); -// IceUtil::Time startJacobian = IceUtil::Time::now(); - Eigen::MatrixXf J = dIK->getJacobianMatrix(tcpNode, mode); - Eigen::MatrixXf Ji = dIK->getPseudoInverseJacobianMatrix(tcpNode, mode); -// ARMARX_INFO << "Jacobian (usec): " << (IceUtil::Time::now() - startJacobian).toMicroSecondsDouble(); + } - // ARMARX_INFO << "TCP Delta (" << tcpDelta.rows() << ")\n" << tcpDelta; - ARMARX_CHECK_EXPRESSION_W_HINT(tcpDelta.rows() == 6 || tcpDelta.rows() == 3, "TCPDelta Vector must have 6 or 3 items"); + void TCPControlUnit::periodicReport() + { + ScopedLock lock(dataMutex); -// IceUtil::Time startCompensation = IceUtil::Time::now(); - Eigen::VectorXf jointLimitCompensation = CalcJointLimitAvoidanceDeltas(robotNodeSet, J, Ji); -// ARMARX_INFO << "Compensation (usec): " << (IceUtil::Time::now() - startCompensation).toMicroSecondsDouble(); + NameValueMap robotConfigMap = remoteRobotPrx->getConfig(); +// NameValueMap::iterator it = robotConfigMap.begin(); + std::map<std::string, float> jointValues(robotConfigMap.begin(), robotConfigMap.end()); - // calculat joint error - Eigen::VectorXf deltaJoint = Ji * (tcpDelta); -// ARMARX_IMPORTANT << deactivateSpam(true, 0.5) << "joint compensation deltas: " << jointLimitCompensation; -// ARMARX_IMPORTANT << deactivateSpam(true, 0.5) << "joint deltas: " << deltaJoint; - deltaJoint += jointLimitCompensation; - return deltaJoint; + localRobot->setJointValues(jointValues); + std::vector<RobotNodeSetPtr > nodeSets = localRobot->getRobotNodeSets(); + FramedPoseBaseMap tcpPoses; + std::string rootFrame = localRobot->getRootNode()->getName(); + for(unsigned int i=0; i < nodeSets.size(); i++) + { + RobotNodeSetPtr nodeSet = nodeSets.at(i); + tcpPoses[nodeSet->getTCP()->getName()]= new FramedPose(nodeSet->getTCP()->getGlobalPose(),rootFrame); + } + listener->reportTCPPose(tcpPoses); } + Eigen::VectorXf TCPControlUnit::CalcJointLimitAvoidanceDeltas(VirtualRobot::RobotNodeSetPtr robotNodeSet, const Eigen::MatrixXf& jacobian, const Eigen::MatrixXf& jacobianInverse, Eigen::VectorXf desiredJointValues) { @@ -401,6 +433,53 @@ namespace armarx getConfigIdentifier())); } + EDifferentialIK::EDifferentialIK(RobotNodeSetPtr rns, RobotNodePtr coordSystem, JacobiProvider::InverseJacobiMethod invJacMethod) : + DifferentialIK(rns, coordSystem, invJacMethod) + { + + } + + Eigen::MatrixXf EDifferentialIK::calcFullJacobian() + { + if (nRows==0) this->setNRows(); + size_t nDoF = nodes.size(); + + using namespace Eigen; + MatrixXf Jacobian(nRows,nDoF); + + size_t index=0; + for (size_t i=0; i<tcp_set.size();i++) + { + RobotNodePtr tcp = tcp_set[i]; + if (this->targets.find(tcp)!=this->targets.end()) + { + IKSolver::CartesianSelection mode = this->modes[tcp]; + MatrixXf partJacobian = this->getJacobianMatrix(tcp,mode); + Jacobian.block(index,0,partJacobian.rows(),nDoF) = partJacobian; + } + else + VR_ERROR << "Internal error?!" << endl; // Error + + + } + return Jacobian; + + } + + void EDifferentialIK::clearGoals() + { + targets.clear(); + modes.clear(); + tolerancePosition.clear(); + toleranceRotation.clear(); + parents.clear(); + } + + void EDifferentialIK::setRefFrame(RobotNodePtr coordSystem) + { + this->coordSystem = coordSystem; + } + } diff --git a/source/RobotAPI/units/TCPControlUnit.h b/source/RobotAPI/units/TCPControlUnit.h index 3da7bb6728d7781b0a6adf7911c6ffe3534a737a..d66e04be6b015669238fc104ab18c48d27a1e5d3 100644 --- a/source/RobotAPI/units/TCPControlUnit.h +++ b/source/RobotAPI/units/TCPControlUnit.h @@ -66,7 +66,7 @@ namespace armarx { // TCPControlUnitInterface interface void setCycleTime(Ice::Int milliseconds, const Ice::Current &c = Ice::Current()); - void setTCPVelocity(const std::string &tcpNodeName, const::armarx::FramedVector3BasePtr &translationVelocity, const::armarx::FramedVector3BasePtr &orientationVelocityRPY, const Ice::Current &c = Ice::Current()); + void setTCPVelocity(const std::string &nodeSetName, const std::string &tcpName, const::armarx::FramedVector3BasePtr &translationVelocity, const::armarx::FramedVector3BasePtr &orientationVelocityRPY, const Ice::Current &c = Ice::Current()); // UnitExecutionManagementInterface interface void init(const Ice::Current &c = Ice::Current()); @@ -85,6 +85,7 @@ namespace armarx { static Eigen::VectorXf CalcJointLimitAvoidanceDeltas(VirtualRobot::RobotNodeSetPtr robotNodeSet, const Eigen::MatrixXf &jacobian, const Eigen::MatrixXf &jacobianInverse, Eigen::VectorXf desiredJointValues = Eigen::VectorXf()); private: void periodicExec(); + void periodicReport(); Eigen::VectorXf calcJointVelocities(VirtualRobot::RobotNodeSetPtr robotNodeSet, Eigen::VectorXf tcpDelta, VirtualRobot::RobotNodePtr refFrame, VirtualRobot::IKSolver::CartesianSelection mode); Eigen::VectorXf applyMaxJointVelocity(const Eigen::VectorXf &jointVelocity, float maxJointVelocity); @@ -92,15 +93,30 @@ namespace armarx { int cycleTime; Eigen::Matrix4f lastTCPPose; - FramedVector3Map targetTranslationVelocities; - FramedVector3Map targetOrientationVelocitiesRPY; + struct TCPVelocityData + { + FramedVector3Ptr translationVelocity; + FramedVector3Ptr orientationVelocity; + std::string nodeSetName; + std::string tcpName; + }; + + typedef std::map<std::string, TCPVelocityData> TCPVelocityDataMap; + TCPVelocityDataMap tcpVelocitiesMap; + + typedef std::map<std::string, VirtualRobot::DifferentialIKPtr> DIKMap; + DIKMap dIKMap; +// FramedVector3Map targetTranslationVelocities; +// FramedVector3Map targetOrientationVelocitiesRPY; PeriodicTask<TCPControlUnit>::pointer_type execTask; + PeriodicTask<TCPControlUnit>::pointer_type topicTask; RobotStateComponentInterfacePrx robotStateComponentPrx; KinematicUnitInterfacePrx kinematicUnitPrx; SharedRobotInterfacePrx remoteRobotPrx; VirtualRobot::RobotPtr localRobot; + TCPControlUnitListenerPrx listener; // VirtualRobot::RobotNodeSetPtr robotNodeSet; // VirtualRobot::DifferentialIKPtr dIK; @@ -109,6 +125,21 @@ namespace armarx { }; + class EDifferentialIK : public VirtualRobot::DifferentialIK + { + public: + EDifferentialIK(VirtualRobot::RobotNodeSetPtr rns,VirtualRobot:: RobotNodePtr coordSystem = VirtualRobot::RobotNodePtr(), VirtualRobot::JacobiProvider::InverseJacobiMethod invJacMethod = eSVD); + + VirtualRobot::RobotNodePtr getRefFrame(){return coordSystem;} + int getJacobianRows(){ return nRows;} + + Eigen::MatrixXf calcFullJacobian(); + + void clearGoals(); + void setRefFrame(VirtualRobot:: RobotNodePtr coordSystem); + }; + typedef boost::shared_ptr<EDifferentialIK> EDifferentialIKPtr; + } #endif diff --git a/source/RobotAPI/units/TCPControlUnitObserver.cpp b/source/RobotAPI/units/TCPControlUnitObserver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..20ae2d59ecdfecab25d2a9681d052aa732ec8e75 --- /dev/null +++ b/source/RobotAPI/units/TCPControlUnitObserver.cpp @@ -0,0 +1,117 @@ +/** +* This file is part of ArmarX. +* +* ArmarX is free software; you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as +* published by the Free Software Foundation; either version 2 of +* the License, or (at your option) any later version. +* +* ArmarX is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* @package ArmarX:: +* @author Mirko Waechter ( mirko.waechter at kit dot edu) +* @date 2013 +* @copyright http://www.gnu.org/licenses/gpl.txt +* GNU General Public License +*/ + +#include "TCPControlUnitObserver.h" + +//#include <Core/robotstate/remote/checks/ConditionCheckEqualsPoseWithTolerance.h> +#include <Core/observers/checks/ConditionCheckUpdated.h> +#include <Core/observers/checks/ConditionCheckEquals.h> +#include <Core/observers/checks/ConditionCheckInRange.h> +#include <Core/observers/checks/ConditionCheckLarger.h> +#include <Core/observers/checks/ConditionCheckSmaller.h> +#include <Core/robotstate/remote/checks/ConditionCheckMagnitudeChecks.h> + +namespace armarx { + + TCPControlUnitObserver::TCPControlUnitObserver() + { + } + + void TCPControlUnitObserver::onInitObserver() + { + usingTopic(getProperty<std::string>("TCPControlUnitName").getValue() + "State"); + + // register all checks + offerConditionCheck("updated", new ConditionCheckUpdated()); + offerConditionCheck("larger", new ConditionCheckLarger()); + offerConditionCheck("equals", new ConditionCheckEquals()); + offerConditionCheck("smaller", new ConditionCheckSmaller()); + // offerConditionCheck("magnitudeinrange", new ConditionCheckInRange()); + offerConditionCheck("magnitudelarger", new ConditionCheckMagnitudeLarger()); +// offerConditionCheck("equalsPoseWithTol", new ConditionCheckEqualsPoseWithTolerance()); + + + offerChannel("TCPPose", "TCP poses of the robot."); + offerChannel("TCPVelocities", "TCP velocities of the robot."); + + } + + void TCPControlUnitObserver::onConnectObserver() + { + + } + + PropertyDefinitionsPtr TCPControlUnitObserver::createPropertyDefinitions() + { + return PropertyDefinitionsPtr(new TCPControlUnitObserverPropertyDefinitions( + getConfigIdentifier())); + } + + void TCPControlUnitObserver::reportTCPPose(const FramedPoseBaseMap &poseMap, const Ice::Current &) + { + ScopedLock lock(dataMutex); + FramedPoseBaseMap::const_iterator it = poseMap.begin(); + for(; it != poseMap.end(); it++) + { + + FramedPosePtr vec = FramedPosePtr::dynamicCast(it->second); + const std::string &tcpName = it->first; + if(!existsDataField("TCPPose", tcpName)) + offerDataFieldWithDefault("TCPPose", tcpName, Variant(it->second), "Pose of " + tcpName); + else + setDataField("TCPPose", tcpName, Variant(it->second)); + + if(!existsChannel(tcpName)) + { + offerChannel(tcpName, "pose components of " + tcpName); + offerDataFieldWithDefault(tcpName,"x", Variant(vec->position->x), "X axis"); + offerDataFieldWithDefault(tcpName,"y", Variant(vec->position->y), "Y axis"); + offerDataFieldWithDefault(tcpName,"z", Variant(vec->position->z), "Z axis"); + offerDataFieldWithDefault(tcpName,"qx", Variant(vec->orientation->qx), "Quaternion part x"); + offerDataFieldWithDefault(tcpName,"qy", Variant(vec->orientation->qy), "Quaternion part y"); + offerDataFieldWithDefault(tcpName,"qz", Variant(vec->orientation->qz), "Quaternion part z"); + offerDataFieldWithDefault(tcpName,"qw", Variant(vec->orientation->qw), "Quaternion part w"); + offerDataFieldWithDefault(tcpName,"frame", Variant(vec->frame), "Reference Frame"); + } + else + { + setDataField(tcpName,"x", Variant(vec->position->x)); + setDataField(tcpName,"y", Variant(vec->position->y)); + setDataField(tcpName,"z", Variant(vec->position->z)); + setDataField(tcpName,"qx", Variant(vec->orientation->qx)); + setDataField(tcpName,"qy", Variant(vec->orientation->qy)); + setDataField(tcpName,"qz", Variant(vec->orientation->qz)); + setDataField(tcpName,"qw", Variant(vec->orientation->qw)); + setDataField(tcpName,"frame", Variant(vec->frame)); + } + + } + } + + void TCPControlUnitObserver::reportTCPVelocities(const FramedVector3Map &, const FramedVector3Map &, const Ice::Current &) + { + } + +} + + diff --git a/source/RobotAPI/units/TCPControlUnitObserver.h b/source/RobotAPI/units/TCPControlUnitObserver.h new file mode 100644 index 0000000000000000000000000000000000000000..727a9a17ac9300ad0afc94865ee4b952a58aa24a --- /dev/null +++ b/source/RobotAPI/units/TCPControlUnitObserver.h @@ -0,0 +1,69 @@ +/** +* This file is part of ArmarX. +* +* ArmarX is free software; you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as +* published by the Free Software Foundation; either version 2 of +* the License, or (at your option) any later version. +* +* ArmarX is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* @package ArmarX:: +* @author Mirko Waechter ( mirko.waechter at kit dot edu) +* @date 2013 +* @copyright http://www.gnu.org/licenses/gpl.txt +* GNU General Public License +*/ +#ifndef _ARMARX_TCPCONTROLUNITOBSERVER_H +#define _ARMARX_TCPCONTROLUNITOBSERVER_H + +#include <Core/observers/Observer.h> +#include <RobotAPI/interface/units/TCPControlUnit.h> + +namespace armarx { + + class TCPControlUnitObserverPropertyDefinitions: + public ComponentPropertyDefinitions + { + public: + TCPControlUnitObserverPropertyDefinitions(std::string prefix): + ComponentPropertyDefinitions(prefix) + { + defineRequiredProperty<std::string>("TCPControlUnitName","Name of the TCPControlUnit"); + } + }; + + class TCPControlUnitObserver : + virtual public Observer, + virtual public TCPControlUnitObserverInterface + { + public: + TCPControlUnitObserver(); + + // framework hooks + virtual std::string getDefaultName() const { return "TCPControlUnitObserver"; } + void onInitObserver(); + void onConnectObserver(); + + /** + * @see PropertyUser::createPropertyDefinitions() + */ + virtual PropertyDefinitionsPtr createPropertyDefinitions(); + + // TCPControlUnitListener interface + public: + void reportTCPPose(const FramedPoseBaseMap &poseMap, const Ice::Current &); + void reportTCPVelocities(const FramedVector3Map &, const FramedVector3Map &, const Ice::Current &); + + Mutex dataMutex; + }; + +} + +#endif