From 34bf6979cd1be5a07850feac00ef3d3c46be5473 Mon Sep 17 00:00:00 2001 From: Simon Ottenhaus <simon.ottenhaus@kit.edu> Date: Wed, 13 May 2020 10:01:55 +0200 Subject: [PATCH] natik --- .../units/GraspCandidateProviderInterface.ice | 1 + .../RobotAPI/libraries/diffik/CMakeLists.txt | 7 + .../libraries/diffik/DiffIKProvider.h | 47 ++ .../libraries/diffik/GraspTrajectory.cpp | 461 ++++++++++++++++++ .../libraries/diffik/GraspTrajectory.h | 151 ++++++ .../libraries/diffik/RobotPlacement.cpp | 68 +++ .../libraries/diffik/RobotPlacement.h | 59 +++ .../libraries/diffik/SimpleDiffIK.cpp | 31 ++ .../RobotAPI/libraries/diffik/SimpleDiffIK.h | 16 + source/RobotAPI/libraries/natik/NaturalIK.cpp | 30 ++ source/RobotAPI/libraries/natik/NaturalIK.h | 16 + 11 files changed, 887 insertions(+) create mode 100644 source/RobotAPI/libraries/diffik/DiffIKProvider.h create mode 100644 source/RobotAPI/libraries/diffik/GraspTrajectory.cpp create mode 100644 source/RobotAPI/libraries/diffik/GraspTrajectory.h create mode 100644 source/RobotAPI/libraries/diffik/RobotPlacement.cpp create mode 100644 source/RobotAPI/libraries/diffik/RobotPlacement.h diff --git a/source/RobotAPI/interface/units/GraspCandidateProviderInterface.ice b/source/RobotAPI/interface/units/GraspCandidateProviderInterface.ice index 8749be775..ebc8cf7c4 100644 --- a/source/RobotAPI/interface/units/GraspCandidateProviderInterface.ice +++ b/source/RobotAPI/interface/units/GraspCandidateProviderInterface.ice @@ -62,6 +62,7 @@ module armarx ApertureType preshape = AnyAperture; ApproachType approach = AnyApproach; string graspTrajectoryName; + string graspTrajectoryPackage; }; class GraspCandidateReachabilityInfo { diff --git a/source/RobotAPI/libraries/diffik/CMakeLists.txt b/source/RobotAPI/libraries/diffik/CMakeLists.txt index 9699d1913..05a777679 100644 --- a/source/RobotAPI/libraries/diffik/CMakeLists.txt +++ b/source/RobotAPI/libraries/diffik/CMakeLists.txt @@ -6,15 +6,22 @@ armarx_set_target("Library: ${LIB_NAME}") set(LIBS ArmarXCore RobotAPICore + StructuralJson + SimpleJsonLogger ) set(LIB_FILES NaturalDiffIK.cpp SimpleDiffIK.cpp + RobotPlacement.cpp + GraspTrajectory.cpp ) set(LIB_HEADERS NaturalDiffIK.h SimpleDiffIK.h + DiffIKProvider.h + RobotPlacement.h + GraspTrajectory.h ) diff --git a/source/RobotAPI/libraries/diffik/DiffIKProvider.h b/source/RobotAPI/libraries/diffik/DiffIKProvider.h new file mode 100644 index 000000000..a75434af4 --- /dev/null +++ b/source/RobotAPI/libraries/diffik/DiffIKProvider.h @@ -0,0 +1,47 @@ +/* + * 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 <Eigen/Dense> + +namespace armarx +{ + typedef boost::shared_ptr<class DiffIKProvider> DiffIKProviderPtr; + + struct DiffIKResult + { + bool reachable; + float posError; + float oriError; + Eigen::VectorXf jointValues; + + }; + class DiffIKProvider + { + public: + virtual DiffIKResult SolveAbsolute(const Eigen::Matrix4f& targetPose) = 0; + virtual DiffIKResult SolveRelative(const Eigen::Matrix4f& targetPose, const Eigen::VectorXf& startJointValues) = 0; + }; +} diff --git a/source/RobotAPI/libraries/diffik/GraspTrajectory.cpp b/source/RobotAPI/libraries/diffik/GraspTrajectory.cpp new file mode 100644 index 000000000..5539a9afb --- /dev/null +++ b/source/RobotAPI/libraries/diffik/GraspTrajectory.cpp @@ -0,0 +1,461 @@ +/* + * 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 + */ + +#include "GraspTrajectory.h" + +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> + +using namespace armarx; + + +GraspTrajectory::Keypoint::Keypoint(const Eigen::Matrix4f& tcpTarget, const Eigen::VectorXf& handJointsTarget) + : tcpTarget(tcpTarget), handJointsTarget(handJointsTarget), dt(0), + feedForwardPosVelocity(0, 0, 0), feedForwardOriVelocity(0, 0, 0), + feedForwardHandJointsVelocity(Eigen::VectorXf::Zero(handJointsTarget.rows())) +{ } + +GraspTrajectory::Keypoint::Keypoint(const Eigen::Matrix4f& tcpTarget, const Eigen::VectorXf& handJointsTarget, + float dt, const Eigen::Vector3f& feedForwardPosVelocity, const Eigen::Vector3f& feedForwardOriVelocity, + const Eigen::VectorXf& feedForwardHandJointsVelocity) + : tcpTarget(tcpTarget), handJointsTarget(handJointsTarget), dt(dt), + feedForwardPosVelocity(feedForwardPosVelocity), feedForwardOriVelocity(feedForwardOriVelocity), + feedForwardHandJointsVelocity(feedForwardHandJointsVelocity) +{ } + +Eigen::Vector3f GraspTrajectory::Keypoint::getTargetPosition() const +{ + return ::math::Helpers::GetPosition(tcpTarget); +} + +Eigen::Matrix3f GraspTrajectory::Keypoint::getTargetOrientation() const +{ + return ::math::Helpers::GetOrientation(tcpTarget); +} + +Eigen::Matrix4f GraspTrajectory::Keypoint::getTargetPose() const +{ + return tcpTarget; +} + +void GraspTrajectory::Keypoint::updateVelocities(const GraspTrajectory::KeypointPtr& prev, float dt) +{ + Eigen::Vector3f pos0 = ::math::Helpers::GetPosition(prev->tcpTarget); + Eigen::Matrix3f ori0 = ::math::Helpers::GetOrientation(prev->tcpTarget); + Eigen::VectorXf hnd0 = prev->handJointsTarget; + + Eigen::Vector3f pos1 = ::math::Helpers::GetPosition(tcpTarget); + Eigen::Matrix3f ori1 = ::math::Helpers::GetOrientation(tcpTarget); + Eigen::VectorXf hnd1 = handJointsTarget; + + Eigen::Vector3f dpos = pos1 - pos0; + Eigen::Vector3f dori = ::math::Helpers::GetRotationVector(ori0, ori1); + Eigen::VectorXf dhnd = hnd1 - hnd0; + + this->dt = dt; + feedForwardPosVelocity = dpos / dt; + feedForwardOriVelocity = dori / dt; + feedForwardHandJointsVelocity = dhnd / dt; +} + +GraspTrajectory::GraspTrajectory(const Eigen::Matrix4f& tcpStart, const Eigen::VectorXf& handJointsStart) +{ + KeypointPtr keypoint(new Keypoint(tcpStart, handJointsStart)); + keypointMap[0] = keypoints.size(); + keypoints.push_back(keypoint); +} + +void GraspTrajectory::addKeypoint(const Eigen::Matrix4f& tcpTarget, const Eigen::VectorXf& handJointsTarget, float dt) +{ + ARMARX_CHECK_EQUAL(GetHandJointCount(), handJointsTarget.rows()); + KeypointPtr prev = lastKeypoint(); + KeypointPtr keypoint(new Keypoint(tcpTarget, handJointsTarget)); + keypoint->updateVelocities(prev, dt); + float t = getDuration() + dt; + keypointMap[t] = keypoints.size(); + keypoints.push_back(keypoint); +} + +size_t GraspTrajectory::getKeypointCount() const +{ + return keypoints.size(); +} + +void GraspTrajectory::insertKeypoint(size_t index, const Eigen::Matrix4f& tcpTarget, const Eigen::VectorXf& handJointsTarget, float dt) +{ + ARMARX_CHECK_EQUAL(GetHandJointCount(), handJointsTarget.rows()); + if (index <= 0 || index > keypoints.size()) + { + throw LocalException("Index out of range" + std::to_string(index)); + } + KeypointPtr prev = keypoints.at(index - 1); + KeypointPtr keypoint(new Keypoint(tcpTarget, handJointsTarget)); + keypoint->updateVelocities(prev, dt); + if (index < keypoints.size()) + { + KeypointPtr next = keypoints.at(index); + next->updateVelocities(keypoint, next->dt); + } + keypoints.insert(keypoints.begin() + index, keypoint); + updateKeypointMap(); +} + +void GraspTrajectory::removeKeypoint(size_t index) +{ + if (index <= 0 || index >= keypoints.size()) + { + throw LocalException("Index out of range" + std::to_string(index)); + } + keypoints.erase(keypoints.begin() + index); + if (index < keypoints.size()) + { + KeypointPtr prev = keypoints.at(index - 1); + KeypointPtr next = keypoints.at(index); + next->updateVelocities(prev, next->dt); + } + updateKeypointMap(); +} + +void GraspTrajectory::replaceKeypoint(size_t index, const Eigen::Matrix4f& tcpTarget, const Eigen::VectorXf& handJointsTarget, float dt) +{ + ARMARX_CHECK_EQUAL(GetHandJointCount(), handJointsTarget.rows()); + if (index <= 0 || index >= keypoints.size()) + { + throw LocalException("Index out of range" + std::to_string(index)); + } + KeypointPtr prev = keypoints.at(index - 1); + KeypointPtr keypoint(new Keypoint(tcpTarget, handJointsTarget)); + keypoint->updateVelocities(prev, dt); + keypoints.at(index) = keypoint; + updateKeypointMap(); +} + +void GraspTrajectory::setKeypointDt(size_t index, float dt) +{ + if (index <= 0 || index >= keypoints.size()) + { + throw LocalException("Index out of range" + std::to_string(index)); + } + KeypointPtr prev = keypoints.at(index - 1); + KeypointPtr& keypoint = keypoints.at(index); + keypoint->updateVelocities(prev, dt); + updateKeypointMap(); +} + +GraspTrajectory::KeypointPtr& GraspTrajectory::lastKeypoint() +{ + return keypoints.at(keypoints.size() - 1); +} + +GraspTrajectory::KeypointPtr& GraspTrajectory::getKeypoint(int i) +{ + return keypoints.at(i); +} + +Eigen::Matrix4f GraspTrajectory::getStartPose() +{ + return getKeypoint(0)->getTargetPose(); +} + +void GraspTrajectory::getIndex(float t, int& i1, int& i2, float& f) +{ + if (t <= 0) + { + i1 = 0; + i2 = 0; + f = 0; + return; + } + std::map<float, size_t>::const_iterator it, prev; + it = keypointMap.upper_bound(t); + if (it == keypointMap.end()) + { + i1 = keypoints.size() - 1; + i2 = keypoints.size() - 1; + f = 0; + return; + } + prev = std::prev(it); + i1 = prev->second; + i2 = it->second; + f = ::math::Helpers::ILerp(prev->first, it->first, t); +} + +Eigen::Vector3f GraspTrajectory::GetPosition(float t) +{ + int i1, i2; + float f; + getIndex(t, i1, i2, f); + return ::math::Helpers::Lerp(getKeypoint(i1)->getTargetPosition(), getKeypoint(i2)->getTargetPosition(), f); +} + +Eigen::Matrix3f GraspTrajectory::GetOrientation(float t) +{ + int i1, i2; + float f; + getIndex(t, i1, i2, f); + Eigen::Vector3f oriVel = GetOrientationDerivative(t); + if (oriVel.squaredNorm() == 0) + { + return getKeypoint(i1)->getTargetOrientation(); + } + Eigen::AngleAxisf aa(oriVel.norm(), oriVel.normalized()); + aa.angle() = aa.angle() * f * getKeypoint(i2)->dt; + return aa.toRotationMatrix() * getKeypoint(i1)->getTargetOrientation(); +} + +Eigen::Matrix4f GraspTrajectory::GetPose(float t) +{ + return ::math::Helpers::CreatePose(GetPosition(t), GetOrientation(t)); +} + +std::vector<Eigen::Matrix4f> GraspTrajectory::getAllKeypointPoses() +{ + std::vector<Eigen::Matrix4f> res; + for (const KeypointPtr& keypoint : keypoints) + { + res.emplace_back(keypoint->getTargetPose()); + } + return res; +} + +std::vector<Eigen::Vector3f> GraspTrajectory::getAllKeypointPositions() +{ + std::vector<Eigen::Vector3f> res; + for (const KeypointPtr& keypoint : keypoints) + { + res.emplace_back(keypoint->getTargetPosition()); + } + return res; +} + +std::vector<Eigen::Matrix3f> GraspTrajectory::getAllKeypointOrientations() +{ + std::vector<Eigen::Matrix3f> res; + for (const KeypointPtr& keypoint : keypoints) + { + res.emplace_back(keypoint->getTargetOrientation()); + } + return res; +} + +Eigen::VectorXf GraspTrajectory::GetHandValues(float t) +{ + int i1, i2; + float f; + getIndex(t, i1, i2, f); + + return getKeypoint(i1)->handJointsTarget * (1 - f) + getKeypoint(i2)->handJointsTarget * f; +} + +Eigen::Vector3f GraspTrajectory::GetPositionDerivative(float t) +{ + int i1, i2; + float f; + getIndex(t, i1, i2, f); + return getKeypoint(i2)->feedForwardPosVelocity; +} + +Eigen::Vector3f GraspTrajectory::GetOrientationDerivative(float t) +{ + int i1, i2; + float f; + getIndex(t, i1, i2, f); + return getKeypoint(i2)->feedForwardOriVelocity; +} + +Eigen::Vector6f GraspTrajectory::GetTcpDerivative(float t) +{ + Eigen::Vector6f ffVel; + ffVel.block<3, 1>(0, 0) = GetPositionDerivative(t); + ffVel.block<3, 1>(3, 0) = GetOrientationDerivative(t); + return ffVel; +} + +Eigen::VectorXf GraspTrajectory::GetHandJointsDerivative(float t) +{ + int i1, i2; + float f; + getIndex(t, i1, i2, f); + return getKeypoint(i2)->feedForwardHandJointsVelocity; +} + +float GraspTrajectory::getDuration() const +{ + return keypointMap.rbegin()->first; +} + +GraspTrajectory::Length GraspTrajectory::calculateLength() const +{ + Length l; + for (size_t i = 1; i < keypoints.size(); i++) + { + KeypointPtr k0 = keypoints.at(i - 1); + KeypointPtr k1 = keypoints.at(i); + + Eigen::Vector3f pos0 = ::math::Helpers::GetPosition(k0->tcpTarget); + Eigen::Matrix3f ori0 = ::math::Helpers::GetOrientation(k0->tcpTarget); + + Eigen::Vector3f pos1 = ::math::Helpers::GetPosition(k1->tcpTarget); + Eigen::Matrix3f ori1 = ::math::Helpers::GetOrientation(k1->tcpTarget); + + l.pos += (pos1 - pos0).norm(); + l.ori += fabs(::math::Helpers::GetAngleAxisFromTo(ori0, ori1).angle()); + } + return l; +} + +int GraspTrajectory::GetHandJointCount() const +{ + return keypoints.at(0)->handJointsTarget.rows(); +} + +GraspTrajectoryPtr GraspTrajectory::getTranslatedAndRotated(const Eigen::Vector3f& translation, const Eigen::Matrix3f& rotation) +{ + GraspTrajectoryPtr traj(new GraspTrajectory(::math::Helpers::TranslateAndRotatePose(getKeypoint(0)->getTargetPose(), translation, rotation), getKeypoint(0)->handJointsTarget)); + for (size_t i = 1; i < keypoints.size(); i++) + { + KeypointPtr& kp = keypoints.at(i); + traj->addKeypoint(::math::Helpers::TranslateAndRotatePose(kp->getTargetPose(), translation, rotation), kp->handJointsTarget, kp->dt); + } + return traj; +} + +GraspTrajectoryPtr GraspTrajectory::getTransformed(const Eigen::Matrix4f& transform) +{ + GraspTrajectoryPtr traj(new GraspTrajectory(transform * getStartPose(), getKeypoint(0)->handJointsTarget)); + for (size_t i = 1; i < keypoints.size(); i++) + { + KeypointPtr& kp = keypoints.at(i); + traj->addKeypoint(transform * kp->getTargetPose(), kp->handJointsTarget, kp->dt); + } + return traj; +} + +GraspTrajectoryPtr GraspTrajectory::getClone() +{ + return getTransformed(Eigen::Matrix4f::Identity()); +} + +GraspTrajectoryPtr GraspTrajectory::getTransformedToGraspPose(const Eigen::Matrix4f& target, const Eigen::Vector3f& handForward) +{ + Eigen::Matrix4f startPose = getStartPose(); + Eigen::Vector3f targetHandForward = ::math::Helpers::TransformDirection(target, handForward); + Eigen::Vector3f trajHandForward = ::math::Helpers::TransformDirection(startPose, handForward); + Eigen::Vector3f up(0, 0, 1); + + float angle = ::math::Helpers::Angle(targetHandForward, trajHandForward, up); + Eigen::AngleAxisf aa(angle, up); + + Eigen::Matrix4f transform = ::math::Helpers::CreateTranslationRotationTranslationPose(-::math::Helpers::GetPosition(startPose), aa.toRotationMatrix(), ::math::Helpers::GetPosition(target)); + return getTransformed(transform); +} + +SimpleDiffIK::Reachability GraspTrajectory::calculateReachability(VirtualRobot::RobotNodeSetPtr rns, VirtualRobot::RobotNodePtr tcp, SimpleDiffIK::Parameters params) +{ + return SimpleDiffIK::CalculateReachability(getAllKeypointPoses(), Eigen::VectorXf::Zero(rns->getSize()), rns, tcp, params); +} + +void GraspTrajectory::writeToFile(const std::string& filename) +{ + RapidXmlWriter writer; + RapidXmlWriterNode root = writer.createRootNode("GraspTrajectory"); + for (const KeypointPtr& keypoint : keypoints) + { + SimpleJsonLoggerEntry e; + e.Add("dt", keypoint->dt); + e.AddAsArr("Pose", keypoint->tcpTarget); + e.AddAsArr("HandValues", keypoint->handJointsTarget); + root.append_string_node("Keypoint", e.obj->toJsonString(0, "", true)); + } + writer.saveToFile(filename, true); +} + +GraspTrajectoryPtr GraspTrajectory::ReadFromFile(const grasping::GraspCandidatePtr& cnd) +{ + std::string packageName = cnd->executionHints->graspTrajectoryPackage; + armarx::CMakePackageFinder finder(packageName); + std::string dataDir = finder.getDataDir() + "/" + packageName; + return GraspTrajectory::ReadFromFile(dataDir + "/motions/grasps/" + cnd->executionHints->graspTrajectoryName + ".xml"); +} + +GraspTrajectoryPtr GraspTrajectory::ReadFromReader(const RapidXmlReaderPtr& reader) +{ + RapidXmlReaderNode root = reader->getRoot("GraspTrajectory"); + GraspTrajectoryPtr traj; + for (const RapidXmlReaderNode& kpNode : root.nodes("Keypoint")) + { + StructuralJsonParser p(kpNode.value()); + p.parse(); + JPathNavigator nav(p.parsedJson); + float dt = nav.selectSingleNode("dt").asFloat(); + + Eigen::Matrix4f pose; + std::vector<JPathNavigator> rows = nav.select("Pose/*"); + for (int i = 0; i < 4; i++) + { + std::vector<JPathNavigator> cells = rows.at(i).select("*"); + for (int j = 0; j < 4; j++) + { + pose(i, j) = cells.at(j).asFloat(); + } + } + + Eigen::Vector3f handValues; + std::vector<JPathNavigator> cells = nav.select("HandValues/*"); + for (int j = 0; j < 3; j++) + { + handValues(j) = cells.at(j).asFloat(); + } + + if (!traj) + { + traj = GraspTrajectoryPtr(new GraspTrajectory(pose, handValues)); + } + else + { + traj->addKeypoint(pose, handValues, dt); + } + } + return traj; +} + +GraspTrajectoryPtr GraspTrajectory::ReadFromFile(const std::string& filename) +{ + return ReadFromReader(RapidXmlReader::FromFile(filename)); +} + +GraspTrajectoryPtr GraspTrajectory::ReadFromString(const std::string& xml) +{ + return ReadFromReader(RapidXmlReader::FromXmlString(xml)); +} + +void GraspTrajectory::updateKeypointMap() +{ + keypointMap.clear(); + float t = 0; + for (size_t i = 0; i < keypoints.size(); i++) + { + t += getKeypoint(i)->dt; + keypointMap[t] = i; + } +} diff --git a/source/RobotAPI/libraries/diffik/GraspTrajectory.h b/source/RobotAPI/libraries/diffik/GraspTrajectory.h new file mode 100644 index 000000000..3e5633d59 --- /dev/null +++ b/source/RobotAPI/libraries/diffik/GraspTrajectory.h @@ -0,0 +1,151 @@ +/* + * 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 <Eigen/Dense> +#include <VirtualRobot/math/AbstractFunctionR1R6.h> +#include <VirtualRobot/math/Helpers.h> +#include <map> +#include <ArmarXCore/core/exceptions/Exception.h> +#include <ArmarXCore/core/rapidxml/wrapper/RapidXmlReader.h> +#include <ArmarXCore/core/rapidxml/wrapper/RapidXmlWriter.h> +#include <RobotAPI/libraries/SimpleJsonLogger/SimpleJsonLogger.h> +#include <ArmarXGui/libraries/StructuralJson/JPathNavigator.h> +#include <ArmarXGui/libraries/StructuralJson/StructuralJsonParser.h> +#include <RobotAPI/libraries/diffik/SimpleDiffIK.h> +#include <RobotAPI/interface/units/GraspCandidateProviderInterface.h> +#include <ArmarXCore/core/system/cmake/CMakePackageFinder.h> +#include <ArmarXCore/interface/serialization/Eigen.h> + +namespace armarx +{ + typedef boost::shared_ptr<class GraspTrajectory> GraspTrajectoryPtr; + + class GraspTrajectory + { + public: + class Keypoint; + typedef boost::shared_ptr<Keypoint> KeypointPtr; + + class Keypoint + { + public: + Eigen::Matrix4f tcpTarget; + Eigen::VectorXf handJointsTarget; + float dt; + Eigen::Vector3f feedForwardPosVelocity; + Eigen::Vector3f feedForwardOriVelocity; + Eigen::VectorXf feedForwardHandJointsVelocity; + + Keypoint(const Eigen::Matrix4f& tcpTarget, const Eigen::VectorXf& handJointsTarget); + Keypoint(const Eigen::Matrix4f& tcpTarget, const Eigen::VectorXf& handJointsTarget, float dt, + const Eigen::Vector3f& feedForwardPosVelocity, const Eigen::Vector3f& feedForwardOriVelocity, + const Eigen::VectorXf& feedForwardHandJointsVelocity); + Eigen::Vector3f getTargetPosition() const; + Eigen::Matrix3f getTargetOrientation() const; + Eigen::Matrix4f getTargetPose() const; + void updateVelocities(const KeypointPtr& prev, float dt); + }; + + struct Length + { + float pos = 0; + float ori = 0; + }; + + + public: + GraspTrajectory(const Eigen::Matrix4f& tcpStart, const Eigen::VectorXf& handJointsStart); + + void addKeypoint(const Eigen::Matrix4f& tcpTarget, const Eigen::VectorXf& handJointsTarget, float dt); + + size_t getKeypointCount() const; + + void insertKeypoint(size_t index, const Eigen::Matrix4f& tcpTarget, const Eigen::VectorXf& handJointsTarget, float dt); + + void removeKeypoint(size_t index); + + void replaceKeypoint(size_t index, const Eigen::Matrix4f& tcpTarget, const Eigen::VectorXf& handJointsTarget, float dt); + + void setKeypointDt(size_t index, float dt); + + KeypointPtr& lastKeypoint(); + KeypointPtr& getKeypoint(int i); + Eigen::Matrix4f getStartPose(); + + void getIndex(float t, int& i1, int& i2, float& f); + + Eigen::Vector3f GetPosition(float t); + + Eigen::Matrix3f GetOrientation(float t); + + Eigen::Matrix4f GetPose(float t); + + std::vector<Eigen::Matrix4f> getAllKeypointPoses(); + std::vector<Eigen::Vector3f> getAllKeypointPositions(); + std::vector<Eigen::Matrix3f> getAllKeypointOrientations(); + + Eigen::VectorXf GetHandValues(float t); + + Eigen::Vector3f GetPositionDerivative(float t); + + Eigen::Vector3f GetOrientationDerivative(float t); + + Eigen::Vector6f GetTcpDerivative(float t); + + Eigen::VectorXf GetHandJointsDerivative(float t); + + float getDuration() const; + + Length calculateLength() const; + int GetHandJointCount() const; + + + GraspTrajectoryPtr getTranslatedAndRotated(const Eigen::Vector3f& translation, const Eigen::Matrix3f& rotation); + GraspTrajectoryPtr getTransformed(const Eigen::Matrix4f& transform); + + GraspTrajectoryPtr getClone(); + + GraspTrajectoryPtr getTransformedToGraspPose(const Eigen::Matrix4f& target, const Eigen::Vector3f& handForward = Eigen::Vector3f::UnitZ()); + + SimpleDiffIK::Reachability calculateReachability(VirtualRobot::RobotNodeSetPtr rns, VirtualRobot::RobotNodePtr tcp = VirtualRobot::RobotNodePtr(), SimpleDiffIK::Parameters params = SimpleDiffIK::Parameters()); + + void writeToFile(const std::string& filename); + + static GraspTrajectoryPtr ReadFromFile(const grasping::GraspCandidatePtr& cnd); + + static GraspTrajectoryPtr ReadFromReader(const RapidXmlReaderPtr& reader); + static GraspTrajectoryPtr ReadFromFile(const std::string& filename); + static GraspTrajectoryPtr ReadFromString(const std::string& xml); + + private: + + void updateKeypointMap(); + + private: + std::vector<KeypointPtr> keypoints; + std::map<float, size_t> keypointMap; + }; +} diff --git a/source/RobotAPI/libraries/diffik/RobotPlacement.cpp b/source/RobotAPI/libraries/diffik/RobotPlacement.cpp new file mode 100644 index 000000000..4075c9aae --- /dev/null +++ b/source/RobotAPI/libraries/diffik/RobotPlacement.cpp @@ -0,0 +1,68 @@ +/* + * 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 + */ + +#include "RobotPlacement.h" + +#include <VirtualRobot/math/Helpers.h> + +using namespace armarx; + +RobotPlacement::RobotPlacement(const DiffIKProviderPtr& ikProvider) +{ +} + +std::vector<Eigen::Matrix4f> RobotPlacement::CreateGrid(float dx, int minx, int maxx, float dy, int miny, int maxy, float da, int mina, int maxa) +{ + std::vector<Eigen::Matrix4f> r; + for (int x = minx; x <= maxx; x++) + for (int y = miny; y <= maxy; y++) + for (int a = mina; a <= maxa; a++) + { + r.emplace_back(math::Helpers::CreatePose(Eigen::Vector3f(x * dx, y * dy, 0), Eigen::AngleAxisf(a * da, Eigen::Vector3f::UnitZ()).toRotationMatrix())); + } + return r; +} + +std::vector<RobotPlacement::Result> RobotPlacement::evaluatePlacements(const std::vector<Eigen::Matrix4f>& robotPlacements, const RobotPlacement::PlacementParams& params) +{ + std::vector<RobotPlacement::Result> r; + std::vector<Eigen::Matrix4f> tcpTargets; + for (const Eigen::Matrix4f& pp : params.prePoses) + { + tcpTargets.emplace_back(pp); + } + std::vector<Eigen::Matrix4f> grasPoses = params.graspTrajectory->getAllKeypointPoses(); + + for (const Eigen::Matrix4f& placement : robotPlacements) + { + Eigen::Matrix4f invPlacement = placement.inverse(); + std::vector<Eigen::Matrix4f> localPoses; + for (const Eigen::Matrix4f& tcpPose : tcpTargets) + { + localPoses.emplace_back(invPlacement * tcpPose); + } + DiffIKResult ikResult = ikProvider->SolveAbsolute(localPoses.at(0)); + throw LocalException("not implemented"); + } + return {}; +} diff --git a/source/RobotAPI/libraries/diffik/RobotPlacement.h b/source/RobotAPI/libraries/diffik/RobotPlacement.h new file mode 100644 index 000000000..a677a7a11 --- /dev/null +++ b/source/RobotAPI/libraries/diffik/RobotPlacement.h @@ -0,0 +1,59 @@ +/* + * 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 "DiffIKProvider.h" +#include "GraspTrajectory.h" + +#include <boost/shared_ptr.hpp> + +namespace armarx +{ + typedef boost::shared_ptr<class RobotPlacement> RobotPlacementPtr; + + class RobotPlacement + { + public: + struct Result + { + DiffIKResult ikResult; + }; + struct PlacementParams + { + std::vector<Eigen::Matrix4f> prePoses; + GraspTrajectoryPtr graspTrajectory; + }; + public: + RobotPlacement(const DiffIKProviderPtr& ikProvider); + + static std::vector<Eigen::Matrix4f> CreateGrid(float dx, int minx, int maxx, float dy, int miny, int maxy, float da, int mina, int maxa); + + std::vector<Result> evaluatePlacements(const std::vector<Eigen::Matrix4f>& robotPlacements, const PlacementParams& params); + + + private: + DiffIKProviderPtr ikProvider; + bool returnOnlyReachable = true; + }; +} diff --git a/source/RobotAPI/libraries/diffik/SimpleDiffIK.cpp b/source/RobotAPI/libraries/diffik/SimpleDiffIK.cpp index 6d0021aec..3e436b8cf 100644 --- a/source/RobotAPI/libraries/diffik/SimpleDiffIK.cpp +++ b/source/RobotAPI/libraries/diffik/SimpleDiffIK.cpp @@ -138,4 +138,35 @@ namespace armarx return r; } + SimpleDiffIKProvider::SimpleDiffIKProvider(VirtualRobot::RobotNodeSetPtr rns, VirtualRobot::RobotNodePtr tcp, SimpleDiffIK::Parameters params) + : rns(rns), tcp(tcp), params(params) + { + } + + DiffIKResult SimpleDiffIKProvider::SolveAbsolute(const Eigen::Matrix4f& targetPose) + { + params.resetRnsValues = true; + SimpleDiffIK::Result result = SimpleDiffIK::CalculateDiffIK(targetPose, rns, tcp, params); + DiffIKResult r; + r.jointValues = rns->getJointValuesEigen(); + r.oriError = result.oriError; + r.posError = result.posError; + r.reachable = result.reached; + return r; + + } + + DiffIKResult SimpleDiffIKProvider::SolveRelative(const Eigen::Matrix4f& targetPose, const Eigen::VectorXf& startJointValues) + { + params.resetRnsValues = false; + rns->setJointValues(startJointValues); + SimpleDiffIK::Result result = SimpleDiffIK::CalculateDiffIK(targetPose, rns, tcp, params); + DiffIKResult r; + r.jointValues = rns->getJointValuesEigen(); + r.oriError = result.oriError; + r.posError = result.posError; + r.reachable = result.reached; + return r; + } + } diff --git a/source/RobotAPI/libraries/diffik/SimpleDiffIK.h b/source/RobotAPI/libraries/diffik/SimpleDiffIK.h index 4ae4e22fa..eeee21dac 100644 --- a/source/RobotAPI/libraries/diffik/SimpleDiffIK.h +++ b/source/RobotAPI/libraries/diffik/SimpleDiffIK.h @@ -23,6 +23,8 @@ #pragma once +#include "DiffIKProvider.h" + #include <boost/shared_ptr.hpp> #include <VirtualRobot/Nodes/RobotNode.h> @@ -109,4 +111,18 @@ namespace armarx ///@brief Use this to check a trajectory of waypoints static Reachability CalculateReachability(const std::vector<Eigen::Matrix4f> targets, const Eigen::VectorXf& initialJV, VirtualRobot::RobotNodeSetPtr rns, VirtualRobot::RobotNodePtr tcp = VirtualRobot::RobotNodePtr(), Parameters params = Parameters()); }; + + class SimpleDiffIKProvider : + public DiffIKProvider + { + public: + SimpleDiffIKProvider(VirtualRobot::RobotNodeSetPtr rns, VirtualRobot::RobotNodePtr tcp = VirtualRobot::RobotNodePtr(), SimpleDiffIK::Parameters params = SimpleDiffIK::Parameters()); + DiffIKResult SolveAbsolute(const Eigen::Matrix4f& targetPose); + DiffIKResult SolveRelative(const Eigen::Matrix4f& targetPose, const Eigen::VectorXf& startJointValues); + + private: + VirtualRobot::RobotNodeSetPtr rns; + VirtualRobot::RobotNodePtr tcp; + SimpleDiffIK::Parameters params; + }; } diff --git a/source/RobotAPI/libraries/natik/NaturalIK.cpp b/source/RobotAPI/libraries/natik/NaturalIK.cpp index 88c57b357..f0ad1b730 100644 --- a/source/RobotAPI/libraries/natik/NaturalIK.cpp +++ b/source/RobotAPI/libraries/natik/NaturalIK.cpp @@ -213,3 +213,33 @@ void NaturalIK::setLowerArmLength(float value) { lowerArmLength = value; } + +NaturalIKProvider::NaturalIKProvider(const NaturalIK& natik, const NaturalIK::ArmJoints& arm, const NaturalDiffIK::Mode& setOri, const NaturalIK::Parameters& params) + : natik(natik), arm(arm), setOri(setOri), params(params) +{ +} + +DiffIKResult NaturalIKProvider::SolveAbsolute(const Eigen::Matrix4f& targetPose) +{ + params.diffIKparams.resetRnsValues = true; + NaturalDiffIK::Result result = natik.calculateIK(targetPose, arm, setOri, params); + DiffIKResult r; + r.jointValues = arm.rns->getJointValuesEigen(); + r.oriError = result.oriError; + r.posError = result.posError; + r.reachable = result.reached; + return r; +} + +DiffIKResult NaturalIKProvider::SolveRelative(const Eigen::Matrix4f& targetPose, const Eigen::VectorXf& startJointValues) +{ + params.diffIKparams.resetRnsValues = false; + arm.rns->setJointValues(startJointValues); + NaturalDiffIK::Result result = natik.calculateIK(targetPose, arm, setOri, params); + DiffIKResult r; + r.jointValues = arm.rns->getJointValuesEigen(); + r.oriError = result.oriError; + r.posError = result.posError; + r.reachable = result.reached; + return r; +} diff --git a/source/RobotAPI/libraries/natik/NaturalIK.h b/source/RobotAPI/libraries/natik/NaturalIK.h index 6db3aa965..d6315096a 100644 --- a/source/RobotAPI/libraries/natik/NaturalIK.h +++ b/source/RobotAPI/libraries/natik/NaturalIK.h @@ -27,6 +27,7 @@ //#include <RobotAPI/libraries/core/SimpleDiffIK.h> #include <VirtualRobot/Nodes/RobotNode.h> +#include <RobotAPI/libraries/diffik/DiffIKProvider.h> #include <RobotAPI/libraries/diffik/NaturalDiffIK.h> #include <optional> @@ -134,4 +135,19 @@ namespace armarx float upperArmLength = SoechtingAngles::MMM_UPPER_ARM_LENGTH; float lowerArmLength = SoechtingAngles::MMM_LOWER_ARM_LENGTH; }; + + class NaturalIKProvider + : public DiffIKProvider + { + public: + NaturalIKProvider(const NaturalIK& natik, const NaturalIK::ArmJoints& arm, const NaturalDiffIK::Mode& setOri, const NaturalIK::Parameters& params = NaturalIK::Parameters()); + DiffIKResult SolveAbsolute(const Eigen::Matrix4f& targetPose); + DiffIKResult SolveRelative(const Eigen::Matrix4f& targetPose, const Eigen::VectorXf& startJointValues); + + private: + NaturalIK natik; + NaturalIK::ArmJoints arm; + NaturalDiffIK::Mode setOri; + NaturalIK::Parameters params; + }; } -- GitLab