diff --git a/data/RobotAPI/VariantInfo-RobotAPI.xml b/data/RobotAPI/VariantInfo-RobotAPI.xml index 6c6ea014be4e39b912e94ac6ff19b61959d3559e..0e6ea498e694f75c9541f9c5e18334ec1f27ba3f 100644 --- a/data/RobotAPI/VariantInfo-RobotAPI.xml +++ b/data/RobotAPI/VariantInfo-RobotAPI.xml @@ -13,6 +13,7 @@ <Variant baseType="::armarx::LinkedDirectionBase" dataType="::armarx::LinkedDirection" humanName="LinkedDirection" include="RobotAPI/libraries/core/LinkedPose.h" /> <Variant baseType="::armarx::OrientedPointBase" dataType="::armarx::OrientedPoint" humanName="OrientedPoint" include="RobotAPI/libraries/core/OrientedPoint.h" /> <Variant baseType="::armarx::FramedOrientedPointBase" dataType="::armarx::FramedOrientedPoint" humanName="FramedOrientedPoint" include="RobotAPI/libraries/core/FramedOrientedPoint.h" /> + <Variant baseType="::armarx::CartesianPositionControllerConfigBase" dataType="::armarx::CartesianPositionControllerConfig" humanName="CartesianPositionControllerConfig" include="RobotAPI/libraries/core/CartesianPositionController.h" /> <Variant baseType="::armarx::TrajectoryBase" dataType="::armarx::Trajectory" humanName="Trajectory" include="RobotAPI/libraries/core/Trajectory.h"/> </Lib> <Lib name="RobotAPIInterfaces"> diff --git a/source/RobotAPI/components/units/GraspCandidateObserver.cpp b/source/RobotAPI/components/units/GraspCandidateObserver.cpp index 467b7b6e180b361294d6a9895abff3edafa63fa6..84ec17f805d3b31e3e3eb7a61a96a4eaae215878 100644 --- a/source/RobotAPI/components/units/GraspCandidateObserver.cpp +++ b/source/RobotAPI/components/units/GraspCandidateObserver.cpp @@ -63,23 +63,23 @@ PropertyDefinitionsPtr GraspCandidateObserver::createPropertyDefinitions() bool GraspCandidateObserver::FilterMatches(const CandidateFilterConditionPtr& filter, const std::string& providerName, const GraspCandidatePtr& candidate) { - if(filter->providerName != "*" && filter->providerName != providerName) + if (filter->providerName != "*" && filter->providerName != providerName) { return false; } - if(filter->minimumSuccessProbability > candidate->graspSuccessProbability) + if (filter->minimumSuccessProbability > candidate->graspSuccessProbability) { return false; } - if(filter->approach != AnyApproach && (candidate->executionHints == 0 || filter->approach != candidate->executionHints->approach)) + if (filter->approach != AnyApproach && (candidate->executionHints == 0 || filter->approach != candidate->executionHints->approach)) { return false; } - if(filter->preshape != AnyAperture && (candidate->executionHints == 0 || filter->preshape != candidate->executionHints->preshape)) + if (filter->preshape != AnyAperture && (candidate->executionHints == 0 || filter->preshape != candidate->executionHints->preshape)) { return false; } - if(filter->objectType != AnyObject && filter->objectType != candidate->objectType) + if (filter->objectType != AnyObject && filter->objectType != candidate->objectType) { return false; } @@ -182,7 +182,7 @@ GraspCandidateSeq GraspCandidateObserver::getAllCandidates(const Ice::Current&) return all; } -GraspCandidateSeq GraspCandidateObserver::getCandidatesByProvider(const std::string& providerName, const Ice::Current&c) +GraspCandidateSeq GraspCandidateObserver::getCandidatesByProvider(const std::string& providerName, const Ice::Current& c) { CandidateFilterConditionPtr filter = new CandidateFilterCondition(); filter->providerName = providerName; @@ -219,14 +219,14 @@ IntMap GraspCandidateObserver::getAllUpdateCounters(const Ice::Current& provider return updateCounters; } -bool GraspCandidateObserver::setProviderConfig(const std::string& providerName, const ConfigMap& config, const Ice::Current&) +bool GraspCandidateObserver::setProviderConfig(const std::string& providerName, const StringVariantBaseMap& config, const Ice::Current&) { ScopedLock lock(dataMutex); if (providers.count(providerName) == 0) { return false; } - configTopic->setGraspCandidateGenerationConfig(providerName, config); + configTopic->setServiceConfig(providerName, config); return true; } diff --git a/source/RobotAPI/components/units/GraspCandidateObserver.h b/source/RobotAPI/components/units/GraspCandidateObserver.h index ade39c3773c9f794b1061ded535a8a4317f48c96..f038c505542fc70e7fe3a1195415c1d0a5489320 100644 --- a/source/RobotAPI/components/units/GraspCandidateObserver.h +++ b/source/RobotAPI/components/units/GraspCandidateObserver.h @@ -84,11 +84,11 @@ namespace armarx grasping::ProviderInfoPtr getProviderInfo(const std::string& providerName, const Ice::Current&) override; bool hasProvider(const std::string& providerName, const Ice::Current& c) override; grasping::GraspCandidateSeq getAllCandidates(const Ice::Current&) override; - grasping::GraspCandidateSeq getCandidatesByProvider(const std::string& providerName, const Ice::Current&c) override; + grasping::GraspCandidateSeq getCandidatesByProvider(const std::string& providerName, const Ice::Current& c) override; grasping::GraspCandidateSeq getCandidatesByFilter(const grasping::CandidateFilterConditionPtr& filter, const Ice::Current&) override; Ice::Int getUpdateCounterByProvider(const std::string& providerName, const Ice::Current&) override; grasping::IntMap getAllUpdateCounters(const Ice::Current& providerName) override; - bool setProviderConfig(const std::string& providerName, const grasping::ConfigMap& config, const Ice::Current&) override; + bool setProviderConfig(const std::string& providerName, const StringVariantBaseMap& config, const Ice::Current&) override; diff --git a/source/RobotAPI/interface/CMakeLists.txt b/source/RobotAPI/interface/CMakeLists.txt index 8250c363f3a4b1e3108bf5fa9306c938ec1510f7..a170a4b5672088d17c85b4b09fd4df9b00c19b25 100644 --- a/source/RobotAPI/interface/CMakeLists.txt +++ b/source/RobotAPI/interface/CMakeLists.txt @@ -18,6 +18,7 @@ set(SLICE_FILES core/RobotStateObserverInterface.ice core/Trajectory.ice core/CartesianSelection.ice + core/CartesianPositionControllerConfig.ice selflocalisation/SelfLocalisationProcess.ice diff --git a/source/RobotAPI/interface/core/CartesianPositionControllerConfig.ice b/source/RobotAPI/interface/core/CartesianPositionControllerConfig.ice new file mode 100644 index 0000000000000000000000000000000000000000..0c1418a257091bead62d86a0629967ba8bfde77b --- /dev/null +++ b/source/RobotAPI/interface/core/CartesianPositionControllerConfig.ice @@ -0,0 +1,49 @@ +/* +* This file is part of ArmarX. +* +* ArmarX is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* 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 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::RobotAPI +* @author Martin Miller +* @copyright 2015 Humanoids Group, KIT +* @license http://www.gnu.org/licenses/gpl-2.0.txt +* GNU General Public License +*/ + +#pragma once + +#include <ArmarXCore/interface/observers/VariantBase.ice> +#include <ArmarXCore/interface/observers/Filters.ice> + +module armarx +{ + /** + * [CartesianPositionControllerConfigBase] defines the config for CartesianPositionController + */ + class CartesianPositionControllerConfigBase extends VariantDataClass + { + float KpPos = 1; + float KpOri = 1; + float maxPosVel = -1; + float maxOriVel = -1; + + float thresholdOrientationNear = -1; + float thresholdOrientationReached = -1; + float thresholdPositionNear = -1; + float thresholdPositionReached = -1; + }; + + + +}; + diff --git a/source/RobotAPI/interface/observers/GraspCandidateObserverInterface.ice b/source/RobotAPI/interface/observers/GraspCandidateObserverInterface.ice index cdae6e66d181ebaeef6082b87151155594a068ea..5dbf43abddd30495ac7e8ab72b36d07f2179c45b 100644 --- a/source/RobotAPI/interface/observers/GraspCandidateObserverInterface.ice +++ b/source/RobotAPI/interface/observers/GraspCandidateObserverInterface.ice @@ -55,7 +55,7 @@ module armarx GraspCandidateSeq getCandidatesByFilter(CandidateFilterCondition filter); int getUpdateCounterByProvider(string providerName); IntMap getAllUpdateCounters(); - bool setProviderConfig(string providerName, ConfigMap config); + bool setProviderConfig(string providerName, StringVariantBaseMap config); }; }; diff --git a/source/RobotAPI/interface/units/GraspCandidateProviderInterface.ice b/source/RobotAPI/interface/units/GraspCandidateProviderInterface.ice index 825b90fc87e51ffdcc2855ec532122fcabc40c6b..25d44c286f17fe43ffecad24162bd55b329a23ec 100644 --- a/source/RobotAPI/interface/units/GraspCandidateProviderInterface.ice +++ b/source/RobotAPI/interface/units/GraspCandidateProviderInterface.ice @@ -26,6 +26,7 @@ #include <ArmarXCore/interface/core/BasicTypes.ice> #include <RobotAPI/interface/core/FramedPoseBase.ice> #include <ArmarXCore/interface/observers/VariantBase.ice> +#include <ArmarXCore/interface/observers/RequestableService.ice> module armarx { @@ -60,6 +61,11 @@ module armarx ApertureType preshape; ApproachType approach; }; + class GraspCandidateReachabilityInfo + { + bool reachable; + float minimumJointLimitMargin; + }; @@ -78,14 +84,15 @@ module armarx GraspCandidateSourceInfo sourceInfo; // (optional) GraspCandidateExecutionHints executionHints; // (optional) + GraspCandidateReachabilityInfo reachabilityInfo; // (optional) }; - dictionary<string, VariantBase> ConfigMap; + class ProviderInfo { ObjectTypeEnum objectType = AnyObject; - ConfigMap currentConfig; + StringVariantBaseMap currentConfig; }; sequence<GraspCandidate> GraspCandidateSeq; @@ -97,10 +104,9 @@ module armarx void reportProviderInfo(string providerName, ProviderInfo info); void reportGraspCandidates(string providerName, GraspCandidateSeq candidates); }; - interface GraspCandidateProviderInterface + + interface GraspCandidateProviderInterface extends RequestableServiceListenerInterface { - void requestGraspCandidateGeneration(string providerName, int timeoutMS); - void setGraspCandidateGenerationConfig(string providerName, ConfigMap config); }; }; diff --git a/source/RobotAPI/libraries/RobotStatechartHelpers/PositionControllerHelper.cpp b/source/RobotAPI/libraries/RobotStatechartHelpers/PositionControllerHelper.cpp index a54cf2fe86393f94a679b1d09d45cb5a7d48f292..a54284c3a03b39a3406b74d83cebae127856a815 100644 --- a/source/RobotAPI/libraries/RobotStatechartHelpers/PositionControllerHelper.cpp +++ b/source/RobotAPI/libraries/RobotStatechartHelpers/PositionControllerHelper.cpp @@ -51,12 +51,34 @@ PositionControllerHelper::PositionControllerHelper(const VirtualRobot::RobotNode } } +void PositionControllerHelper::readConfig(const CartesianPositionControllerConfigBasePtr& config) +{ + thresholdOrientationNear = config->thresholdOrientationNear; + thresholdOrientationReached = config->thresholdOrientationReached; + thresholdPositionNear = config->thresholdPositionNear; + thresholdPositionReached = config->thresholdPositionReached; + posController.KpOri = config->KpOri; + posController.KpPos = config->KpPos; + posController.maxOriVel = config->maxOriVel; + posController.maxPosVel = config->maxPosVel; +} + void PositionControllerHelper::update() +{ + updateRead(); + updateWrite(); +} + +void PositionControllerHelper::updateRead() { if (!isLastWaypoint() && isCurrentTargetNear()) { currentWaypointIndex++; } +} + +void PositionControllerHelper::updateWrite() +{ Eigen::VectorXf cv = posController.calculate(getCurrentTarget(), VirtualRobot::IKSolver::All); velocityControllerHelper->setTargetVelocity(cv + feedForwardVelocity); if (autoClearFeedForward) @@ -109,6 +131,15 @@ void PositionControllerHelper::clearFeedForwardVelocity() feedForwardVelocity = Eigen::Vector6f::Zero(); } +void PositionControllerHelper::immediateHardStop(bool clearTargets) +{ + velocityControllerHelper->controller->immediateHardStop(); + if (clearTargets) + { + setTarget(posController.getTcp()->getPoseInRootFrame()); + } +} + float PositionControllerHelper::getPositionError() const { return posController.getPositionError(getCurrentTarget()); diff --git a/source/RobotAPI/libraries/RobotStatechartHelpers/PositionControllerHelper.h b/source/RobotAPI/libraries/RobotStatechartHelpers/PositionControllerHelper.h index e4012fbb5ce8c99f951eea53833d11f352571771..e7268120ab1132cf2aa7a77c4b449fd3d0a1faac 100644 --- a/source/RobotAPI/libraries/RobotStatechartHelpers/PositionControllerHelper.h +++ b/source/RobotAPI/libraries/RobotStatechartHelpers/PositionControllerHelper.h @@ -53,7 +53,15 @@ namespace armarx PositionControllerHelper(const VirtualRobot::RobotNodePtr& tcp, const VelocityControllerHelperPtr& velocityControllerHelper, const std::vector<Eigen::Matrix4f>& waypoints); PositionControllerHelper(const VirtualRobot::RobotNodePtr& tcp, const VelocityControllerHelperPtr& velocityControllerHelper, const std::vector<PosePtr>& waypoints); + void readConfig(const CartesianPositionControllerConfigBasePtr& config); + + // read data and write targets, call this if you are unsure, anywhere in your control loop. + // use updateRead and updateWrite for better performance void update(); + // read data, call this after robot sync + void updateRead(); + // write targets, call this at the end of your control loop, before the sleep + void updateWrite(); void setNewWaypoints(const std::vector<Eigen::Matrix4f>& waypoints); void setNewWaypoints(const std::vector<PosePtr>& waypoints); @@ -62,6 +70,7 @@ namespace armarx void setFeedForwardVelocity(const Eigen::Vector6f& feedForwardVelocity); void setFeedForwardVelocity(const Eigen::Vector3f& feedForwardVelocityPos, const Eigen::Vector3f& feedForwardVelocityOri); void clearFeedForwardVelocity(); + void immediateHardStop(bool clearTargets = true); float getPositionError() const; diff --git a/source/RobotAPI/libraries/core/CMakeLists.txt b/source/RobotAPI/libraries/core/CMakeLists.txt index f089984659762898e5da278375c627656d8d375f..33566020ec5bb244c21719c4d9b323ae6a2896c2 100644 --- a/source/RobotAPI/libraries/core/CMakeLists.txt +++ b/source/RobotAPI/libraries/core/CMakeLists.txt @@ -47,6 +47,7 @@ set(LIB_FILES CartesianVelocityRamp.cpp JointVelocityRamp.cpp CartesianVelocityControllerWithRamp.cpp + SimpleDiffIK.cpp ) set(LIB_HEADERS @@ -90,6 +91,7 @@ set(LIB_HEADERS CartesianVelocityRamp.h JointVelocityRamp.h CartesianVelocityControllerWithRamp.h + SimpleDiffIK.h EigenHelpers.h ) diff --git a/source/RobotAPI/libraries/core/CartesianPositionController.cpp b/source/RobotAPI/libraries/core/CartesianPositionController.cpp index 4559e139c7d93e803f1ff7d070a77698396863a0..60c62092f4e34302e825e530436e150204f91fe5 100644 --- a/source/RobotAPI/libraries/core/CartesianPositionController.cpp +++ b/source/RobotAPI/libraries/core/CartesianPositionController.cpp @@ -100,3 +100,64 @@ Eigen::Vector3f CartesianPositionController::getOrientationDiff(const Eigen::Mat Eigen::AngleAxisf aa(oriDir); return aa.axis() * aa.angle(); } + +VirtualRobot::RobotNodePtr CartesianPositionController::getTcp() const +{ + return tcp; +} + + + +#define SS_OUT(x) ss << #x << " = " << x << "\n" +#define SET_FLT(x) obj->setFloat(#x, x) +#define GET_FLT(x) x = obj->getFloat(#x); + +CartesianPositionControllerConfig::CartesianPositionControllerConfig() +{ +} + +std::string CartesianPositionControllerConfig::output(const Ice::Current& c) const +{ + std::stringstream ss; + + SS_OUT(KpPos); + SS_OUT(KpOri); + SS_OUT(maxPosVel); + SS_OUT(maxOriVel); + SS_OUT(thresholdOrientationNear); + SS_OUT(thresholdOrientationReached); + SS_OUT(thresholdPositionNear); + SS_OUT(thresholdPositionReached); + + return ss.str(); +} + +void CartesianPositionControllerConfig::serialize(const ObjectSerializerBasePtr& serializer, const Ice::Current&) const +{ + AbstractObjectSerializerPtr obj = AbstractObjectSerializerPtr::dynamicCast(serializer); + + SET_FLT(KpPos); + SET_FLT(KpOri); + SET_FLT(maxPosVel); + SET_FLT(maxOriVel); + SET_FLT(thresholdOrientationNear); + SET_FLT(thresholdOrientationReached); + SET_FLT(thresholdPositionNear); + SET_FLT(thresholdPositionReached); + +} + +void CartesianPositionControllerConfig::deserialize(const ObjectSerializerBasePtr& serializer, const Ice::Current&) +{ + AbstractObjectSerializerPtr obj = AbstractObjectSerializerPtr::dynamicCast(serializer); + + GET_FLT(KpPos); + GET_FLT(KpOri); + GET_FLT(maxPosVel); + GET_FLT(maxOriVel); + GET_FLT(thresholdOrientationNear); + GET_FLT(thresholdOrientationReached); + GET_FLT(thresholdPositionNear); + GET_FLT(thresholdPositionReached); + +} diff --git a/source/RobotAPI/libraries/core/CartesianPositionController.h b/source/RobotAPI/libraries/core/CartesianPositionController.h index 2c4b46c5c2363938a47555ca9407a0f495e0353a..3333a45fa98a16c7dcd85ac21443a434d1bc5af1 100644 --- a/source/RobotAPI/libraries/core/CartesianPositionController.h +++ b/source/RobotAPI/libraries/core/CartesianPositionController.h @@ -30,6 +30,10 @@ #include <VirtualRobot/Robot.h> #include <Eigen/Dense> +#include <RobotAPI/interface/core/CartesianPositionControllerConfig.h> +#include <ArmarXCore/observers/variant/Variant.h> +#include <ArmarXCore/observers/AbstractObjectSerializer.h> + namespace armarx { class CartesianPositionController; @@ -47,6 +51,7 @@ namespace armarx float getOrientationError(const Eigen::Matrix4f& targetPose) const; Eigen::Vector3f getPositionDiff(const Eigen::Matrix4f& targetPose) const; Eigen::Vector3f getOrientationDiff(const Eigen::Matrix4f& targetPose) const; + VirtualRobot::RobotNodePtr getTcp() const; float KpPos = 1; float KpOri = 1; @@ -57,5 +62,50 @@ namespace armarx private: VirtualRobot::RobotNodePtr tcp; }; + + namespace VariantType + { + // variant types + const VariantTypeId CartesianPositionControllerConfig = Variant::addTypeName("::armarx::CartesianPositionControllerConfig"); + } + + class CartesianPositionControllerConfig : virtual public CartesianPositionControllerConfigBase + { + public: + CartesianPositionControllerConfig(); + + + // inherited from VariantDataClass + Ice::ObjectPtr ice_clone() const override + { + return this->clone(); + } + VariantDataClassPtr clone(const Ice::Current& = ::Ice::Current()) const override + { + return new CartesianPositionControllerConfig(*this); + } + std::string output(const Ice::Current& c = ::Ice::Current()) const override; + VariantTypeId getType(const Ice::Current& = ::Ice::Current()) const override + { + return VariantType::CartesianPositionControllerConfig; + } + bool validate(const Ice::Current& = ::Ice::Current()) override + { + return true; + } + + friend std::ostream& operator<<(std::ostream& stream, const CartesianPositionControllerConfig& rhs) + { + stream << "CartesianPositionControllerConfig: " << std::endl << rhs.output() << std::endl; + return stream; + } + + public: // serialization + void serialize(const armarx::ObjectSerializerBasePtr& serializer, const ::Ice::Current& = ::Ice::Current()) const override; + void deserialize(const armarx::ObjectSerializerBasePtr& serializer, const ::Ice::Current& = ::Ice::Current()) override; + + }; + + typedef IceInternal::Handle<CartesianPositionControllerConfig> CartesianPositionControllerConfigPtr; } diff --git a/source/RobotAPI/libraries/core/CartesianVelocityController.cpp b/source/RobotAPI/libraries/core/CartesianVelocityController.cpp index 3ec8849c620e0abbc05a548f625a771b76839199..0f84e0a0a2e54981497c4723009f297800e2bc02 100644 --- a/source/RobotAPI/libraries/core/CartesianVelocityController.cpp +++ b/source/RobotAPI/libraries/core/CartesianVelocityController.cpp @@ -119,6 +119,7 @@ Eigen::VectorXf CartesianVelocityController::calculateJointLimitAvoidance() { float f = math::MathUtils::ILerp(rn->getJointLimitLo(), rn->getJointLimitHi(), rn->getJointValue()); r(i) = cos(f * M_PI); + //r(i) = math::MathUtils::Lerp(1.f, -1.f, f); } } return r; diff --git a/source/RobotAPI/libraries/core/RobotAPIObjectFactories.cpp b/source/RobotAPI/libraries/core/RobotAPIObjectFactories.cpp index e2d22fa0e321fc0ce6c3699466fc24b5002755c0..4305b29ceb6166b81d238e2309c799db83ce1e66 100644 --- a/source/RobotAPI/libraries/core/RobotAPIObjectFactories.cpp +++ b/source/RobotAPI/libraries/core/RobotAPIObjectFactories.cpp @@ -36,6 +36,7 @@ #include <RobotAPI/libraries/core/observerfilters/MedianDerivativeFilterV3.h> #include <RobotAPI/libraries/core/OrientedPoint.h> #include <RobotAPI/libraries/core/FramedOrientedPoint.h> +#include <RobotAPI/libraries/core/CartesianPositionController.h> using namespace armarx; @@ -58,6 +59,7 @@ ObjectFactoryMap RobotAPIObjectFactories::getFactories() add<armarx::OrientedPointBase, armarx::OrientedPoint>(map); add<armarx::FramedOrientedPointBase, armarx::FramedOrientedPoint>(map); + add<armarx::CartesianPositionControllerConfigBase, armarx::CartesianPositionControllerConfig>(map); add<armarx::PoseMedianFilterBase, armarx::filters::PoseMedianFilter>(map); add<armarx::PoseAverageFilterBase, armarx::filters::PoseAverageFilter>(map); diff --git a/source/RobotAPI/libraries/core/SimpleDiffIK.cpp b/source/RobotAPI/libraries/core/SimpleDiffIK.cpp new file mode 100644 index 0000000000000000000000000000000000000000..aa25dffbb3d01bd4df15205e118ec2de1ab360e7 --- /dev/null +++ b/source/RobotAPI/libraries/core/SimpleDiffIK.cpp @@ -0,0 +1,85 @@ +/* + * This file is part of ArmarX. + * + * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T), + * Karlsruhe Institute of Technology (KIT), all rights reserved. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 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/>. + * + * @author SecondHands Demo (shdemo at armar6) + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#include "CartesianPositionController.h" +#include "CartesianVelocityController.h" +#include "SimpleDiffIK.h" + +using namespace armarx; + + + +SimpleDiffIK::Result SimpleDiffIK::CalculateDiffIK(const Eigen::Matrix4f targetPose, VirtualRobot::RobotNodeSetPtr rns, VirtualRobot::RobotNodePtr tcp, Parameters params) +{ + tcp = tcp ? tcp : rns->getTCP(); + CartesianVelocityController velocityController(rns); + CartesianPositionController positionController(tcp); + + for (size_t i = 0; i <= params.stepsInitial + params.stepsFineTune; i++) + { + Eigen::Vector3f posDiff = positionController.getPositionDiff(targetPose); + Eigen::Vector3f oriDiff = positionController.getOrientationDiff(targetPose); + + //ARMARX_IMPORTANT << VAROUT(posDiff) << VAROUT(oriDiff); + + Eigen::VectorXf cartesialVel(6); + cartesialVel << posDiff(0), posDiff(1), posDiff(2), oriDiff(0), oriDiff(1), oriDiff(2); + Eigen::VectorXf jnv = params.jointLimitAvoidanceKp * velocityController.calculateJointLimitAvoidance(); + Eigen::VectorXf jv = velocityController.calculate(cartesialVel, jnv, VirtualRobot::IKSolver::All); + + + float stepLength = i < params.stepsInitial ? params.ikStepLengthInitial : params.ikStepLengthFineTune; + jv = jv * stepLength; + + for (size_t n = 0; n < rns->getSize(); n++) + { + rns->getNode(n)->setJointValue(rns->getNode(n)->getJointValue() + jv(n)); + } + } + + Result result; + result.jointValues = rns->getJointValuesEigen(); + result.posDiff = positionController.getPositionDiff(targetPose); + result.oriDiff = positionController.getOrientationDiff(targetPose); + result.posError = positionController.getPositionError(targetPose); + result.oriError = positionController.getOrientationError(targetPose); + result.reached = result.posError < params.maxPosError && result.oriError < params.maxOriError; + + result.jointLimitMargins = Eigen::VectorXf::Zero(rns->getSize()); + result.minimumJointLimitMargin = FLT_MAX; + for (size_t i = 0; i < rns->getSize(); i++) + { + VirtualRobot::RobotNodePtr rn = rns->getNode(i); + if (rn->isLimitless()) + { + result.jointLimitMargins(i) = M_PI; + } + else + { + result.jointLimitMargins(i) = std::min(rn->getJointValue() - rn->getJointLimitLo(), rn->getJointLimitHi() - rn->getJointValue()); + result.minimumJointLimitMargin = std::min(result.minimumJointLimitMargin, result.jointLimitMargins(i)); + } + } + + return result; +} diff --git a/source/RobotAPI/libraries/core/SimpleDiffIK.h b/source/RobotAPI/libraries/core/SimpleDiffIK.h new file mode 100644 index 0000000000000000000000000000000000000000..9f3302118b93230dd03cd402e04081314cc11ef5 --- /dev/null +++ b/source/RobotAPI/libraries/core/SimpleDiffIK.h @@ -0,0 +1,65 @@ +/* + * This file is part of ArmarX. + * + * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T), + * Karlsruhe Institute of Technology (KIT), all rights reserved. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 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/>. + * + * @author Simon Ottenhaus (simon dot ottenhaus at kit dot edu) + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#pragma once + +#include <boost/shared_ptr.hpp> + +#include <VirtualRobot/Nodes/RobotNode.h> +#include <VirtualRobot/RobotNodeSet.h> + +namespace armarx +{ + typedef boost::shared_ptr<class SimpleDiffIK> SimpleDiffIKPtr; + + class SimpleDiffIK + { + public: + struct Parameters + { + Parameters() {} + // IK params + float ikStepLengthInitial = 0.2f; + float ikStepLengthFineTune = 0.5f; + size_t stepsInitial = 25; + size_t stepsFineTune = 5; + float maxPosError = 10.f; + float maxOriError = 0.05f; + float jointLimitAvoidanceKp = 2.0f; + }; + struct Result + { + Eigen::VectorXf jointValues; + Eigen::Vector3f posDiff; + Eigen::Vector3f oriDiff; + float posError; + float oriError; + bool reached; + Eigen::VectorXf jointLimitMargins; + float minimumJointLimitMargin; + }; + + static Result CalculateDiffIK(const Eigen::Matrix4f targetPose, VirtualRobot::RobotNodeSetPtr rns, VirtualRobot::RobotNodePtr tcp = VirtualRobot::RobotNodePtr(), Parameters params = Parameters()); + + }; +} diff --git a/source/RobotAPI/libraries/core/SimpleGridReachability.cpp b/source/RobotAPI/libraries/core/SimpleGridReachability.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c13ea798af6433f002e02832de70ac8093834d4f --- /dev/null +++ b/source/RobotAPI/libraries/core/SimpleGridReachability.cpp @@ -0,0 +1,44 @@ +#include "CartesianVelocityController.h" +#include "SimpleGridReachability.h" + +using namespace armarx; + + +SimpleGridReachability::Result SimpleGridReachability::calculateDiffIK(const Eigen::Matrix4f targetPose, const Parameters& params) +{ + VirtualRobot::RobotNodePtr rns = params.nodeSet; + VirtualRobot::RobotNodeSetPtr tcp = params.tcp ? params.tcp : rns->getTCP(); + CartesianVelocityController velocityController(rns); + CartesianPositionController positionController(tcp); + + Eigen::VectorXf initialJV = rns->getJointValuesEigen(); + for (size_t i = 0; i <= params.stepsInitial + params.stepsFineTune; i++) + { + Eigen::Vector3f posDiff = positionController.getPositionDiff(targetPose); + Eigen::Vector3f oriDiff = positionController.getOrientationDiff(targetPose); + + //ARMARX_IMPORTANT << VAROUT(posDiff) << VAROUT(oriDiff); + + Eigen::VectorXf cartesialVel(6); + cartesialVel << posDiff(0), posDiff(1), posDiff(2), oriDiff(0), oriDiff(1), oriDiff(2); + Eigen::VectorXf jnv = params.jointLimitAvoidanceKp * velocityController.calculateJointLimitAvoidance(); + Eigen::VectorXf jv = velocityController.calculate(cartesialVel, jnv, VirtualRobot::IKSolver::All); + + + float stepLength = i < params.stepsInitial ? params.ikStepLengthInitial : params.ikStepLengthFineTune; + jv = jv * stepLength; + + for (size_t n = 0; n < rns->getSize(); n++) + { + rns->getNode(n)->setJointValue(rns->getNode(n)->getJointValue() + jv(n)); + } + } + + Result result; + result.jointValues = rns->getJointValuesEigen(); + result.posError = positionController.getPositionDiff(targetPose); + result.oriError = positionController.getOrientationError(targetPose); + result.reached = result.posError < params.maxPosError && result.oriError < params.maxOriError; + + return result; +} diff --git a/source/RobotAPI/libraries/core/SimpleGridReachability.h b/source/RobotAPI/libraries/core/SimpleGridReachability.h new file mode 100644 index 0000000000000000000000000000000000000000..4ac9bc70f16524bbf86cbba53efc5f034a5c4f96 --- /dev/null +++ b/source/RobotAPI/libraries/core/SimpleGridReachability.h @@ -0,0 +1,37 @@ +#pragma once +#include "CartesianPositionController.h" + +namespace armarx +{ + class SimpleGridReachability + { + public: + struct Parameters + { + VirtualRobot::RobotNodePtr tcp; + VirtualRobot::RobotNodeSetPtr nodeSet; + + // IK params + float ikStepLengthInitial = 0.2f; + float ikStepLengthFineTune = 0.5f; + size_t stepsInitial = 25; + size_t stepsFineTune = 5; + float maxPosError = 10.f; + float maxOriError = 0.05f; + float jointLimitAvoidanceKp = 2.0f; + }; + struct Result + { + Eigen::VectorXf jointValues; + float posError; + float oriError; + bool reached; + }; + + static Result CalculateDiffIK(const Eigen::Matrix4f targetPose, const Parameters& params); + + + }; + +} +