diff --git a/source/RobotAPI/components/ArViz/CMakeLists.txt b/source/RobotAPI/components/ArViz/CMakeLists.txt index 23bc568751839f9758cd09597b2b4f58b8b5e419..9a5a3adcbfedd3a756b8231b61db7591ad66047b 100644 --- a/source/RobotAPI/components/ArViz/CMakeLists.txt +++ b/source/RobotAPI/components/ArViz/CMakeLists.txt @@ -15,12 +15,16 @@ set(SOURCES Client/elements/Mesh.cpp Client/elements/Robot.cpp Client/elements/RobotHand.cpp + Client/elements/Line.cpp + Client/elements/Path.cpp + Client/drawer/ArVizDrawerBase.cpp Client/ScopedClient.cpp Coin/ElementVisualizer.cpp Coin/VisualizationRobot.cpp + Coin/VisualizationPath.cpp Coin/VisualizationObject.cpp Coin/Visualizer.cpp @@ -49,6 +53,7 @@ set(HEADERS Coin/VisualizationEllipsoid.h Coin/VisualizationSphere.h Coin/VisualizationPose.h + Coin/VisualizationPath.h Coin/VisualizationLine.h Coin/VisualizationText.h Coin/VisualizationArrow.h @@ -77,6 +82,8 @@ set(HEADERS Client/elements/PointCloud.h Client/elements/Robot.h Client/elements/RobotHand.h + Client/elements/Line.h + Client/elements/Path.h Client/drawer/ArVizDrawerBase.h diff --git a/source/RobotAPI/components/ArViz/Client/elements/Line.cpp b/source/RobotAPI/components/ArViz/Client/elements/Line.cpp new file mode 100644 index 0000000000000000000000000000000000000000..985162f1726a66c88c4a310e6b287641294fa9f9 --- /dev/null +++ b/source/RobotAPI/components/ArViz/Client/elements/Line.cpp @@ -0,0 +1,20 @@ +#include "Line.h" + +#include "ArmarXCore/interface/core/BasicVectorTypesHelpers.h" + +namespace armarx::viz +{ + Line& Line::lineWidth(float w) + { + data_->lineWidth = w; + + return *this; + } + Line& Line::fromTo(Eigen::Vector3f from, Eigen::Vector3f to) + { + data_->from = ToBasicVectorType(from); + data_->to = ToBasicVectorType(to); + + return *this; + } +} // namespace armarx::viz \ No newline at end of file diff --git a/source/RobotAPI/components/ArViz/Client/elements/Line.h b/source/RobotAPI/components/ArViz/Client/elements/Line.h new file mode 100644 index 0000000000000000000000000000000000000000..6f6d9427e05b9d91606e8ecdfa8a2164f4847515 --- /dev/null +++ b/source/RobotAPI/components/ArViz/Client/elements/Line.h @@ -0,0 +1,38 @@ +/* + * 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/>. + * + * @author Fabian Reister ( fabian dot reister at kit dot edu ) + * @date 2021 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#pragma once + +#include "RobotAPI/components/ArViz/Client/elements/ElementOps.h" +#include <RobotAPI/interface/ArViz/Elements.h> + +namespace armarx::viz +{ + class Line : public ElementOps<Line, data::ElementLine> + { + public: + using ElementOps::ElementOps; + + Line& lineWidth(float w); + + Line& fromTo(Eigen::Vector3f from, Eigen::Vector3f to); + }; +} // namespace armarx::viz diff --git a/source/RobotAPI/components/ArViz/Client/elements/Path.cpp b/source/RobotAPI/components/ArViz/Client/elements/Path.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0a88d089382eebb915104c24ee41339a18dd2f29 --- /dev/null +++ b/source/RobotAPI/components/ArViz/Client/elements/Path.cpp @@ -0,0 +1,51 @@ +#include "Path.h" + +namespace armarx::viz +{ + + Path& Path::clear() + { + data_->points.clear(); + return *this; + } + + Path& Path::lineColor(Color color) + { + data_->lineColor = color; + + return *this; + } + + Path& Path::lineColorGlasbeyLUT(std::size_t id, int alpha) + { + return lineColor(Color::fromRGBA(simox::color::GlasbeyLUT::at(id, alpha))); + } + + Path& Path::lineWidth(float w) + { + data_->lineWidth = w; + + return *this; + } + + Path& Path::points(std::vector<Eigen::Vector3f> const& ps) + { + auto& points = data_->points; + points.clear(); + points.reserve(ps.size()); + for (auto& p : ps) + { + points.push_back(armarx::Vector3f{p.x(), p.y(), p.z()}); + } + + return *this; + } + + Path& Path::addPoint(Eigen::Vector3f p) + { + data_->points.push_back(armarx::Vector3f{p.x(), p.y(), p.z()}); + + return *this; + } + +} // namespace armarx::viz \ No newline at end of file diff --git a/source/RobotAPI/components/ArViz/Client/elements/Path.h b/source/RobotAPI/components/ArViz/Client/elements/Path.h new file mode 100644 index 0000000000000000000000000000000000000000..50eec6abe454bbf56bc45053c4d35f5e41ca5bc6 --- /dev/null +++ b/source/RobotAPI/components/ArViz/Client/elements/Path.h @@ -0,0 +1,59 @@ + + +/* + * 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/>. + * + * @author Fabian Reister ( fabian dot reister at kit dot edu ) + * @date 2021 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#pragma once + +#include "RobotAPI/components/ArViz/Client/elements/ElementOps.h" +#include <RobotAPI/interface/ArViz/Elements.h> + +namespace armarx::viz +{ + class Path : public ElementOps<Path, data::ElementPath> + { + public: + using ElementOps::ElementOps; + + Path& clear(); + + Path& lineColor(Color color); + + template<class...Ts> + Path& lineColor(Ts&& ...ts) + { + return lineColor({std::forward<Ts>(ts)...}); + } + + Path& lineColorGlasbeyLUT(std::size_t id, int alpha = 255); + + Path& lineWidth(float w); + + Path& points(std::vector<Eigen::Vector3f> const& ps); + + Path& addPoint(Eigen::Vector3f p); + }; +} // namespace armarx::viz + + + + + diff --git a/source/RobotAPI/components/ArViz/Coin/RegisterVisualizationTypes.cpp b/source/RobotAPI/components/ArViz/Coin/RegisterVisualizationTypes.cpp index 33febe24be91fd428f06762cbcfc6d7e48f101a0..5ca14001aff6c7be187ad4c7736e86fd3ab6b3c6 100644 --- a/source/RobotAPI/components/ArViz/Coin/RegisterVisualizationTypes.cpp +++ b/source/RobotAPI/components/ArViz/Coin/RegisterVisualizationTypes.cpp @@ -15,13 +15,14 @@ #include "VisualizationMesh.h" #include "VisualizationRobot.h" #include "VisualizationObject.h" +#include "VisualizationPath.h" void armarx::viz::CoinVisualizer::registerVisualizationTypes() { using namespace armarx::viz::coin; - elementVisualizers.reserve(15); + elementVisualizers.reserve(16); registerVisualizerFor<VisualizationBox>(); registerVisualizerFor<VisualizationCylinder>(); @@ -38,4 +39,5 @@ void armarx::viz::CoinVisualizer::registerVisualizationTypes() registerVisualizerFor<VisualizationMesh>(); registerVisualizerFor<VisualizationRobot>(); registerVisualizerFor<VisualizationObject>(); + registerVisualizerFor<VisualizationPath>(); } diff --git a/source/RobotAPI/components/ArViz/Coin/VisualizationPath.cpp b/source/RobotAPI/components/ArViz/Coin/VisualizationPath.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3018a3af51e25222b97c0c60ed06fea65a8c5822 --- /dev/null +++ b/source/RobotAPI/components/ArViz/Coin/VisualizationPath.cpp @@ -0,0 +1,63 @@ +#include "VisualizationPath.h" + +#include <Inventor/SbVec3f.h> +#include <Inventor/nodes/SoCoordinate3.h> +#include <Inventor/nodes/SoDrawStyle.h> +#include <Inventor/nodes/SoLineSet.h> + +namespace armarx::viz::coin +{ + + VisualizationPath::VisualizationPath() + { + coordinate3 = new SoCoordinate3; + + // create line around polygon + SoSeparator* lineSep = new SoSeparator; + + lineMaterial = new SoMaterial; + lineSep->addChild(lineMaterial); + lineSep->addChild(coordinate3); + + lineStyle = new SoDrawStyle(); + lineSep->addChild(lineStyle); + + lineSet = new SoLineSet; + lineSep->addChild(lineSet); + + node->addChild(coordinate3); + node->addChild(lineSep); + } + + bool VisualizationPath::update(ElementType const& element) + { + // set position + coordinate3->point.setValuesPointer(element.points.size(), reinterpret_cast<const float*>(element.points.data())); + + // set color + const auto lineColor = element.lineColor; + + constexpr float toUnit = 1.0F / 255.0F; + + const auto color = SbVec3f(lineColor.r, lineColor.g, lineColor.b) * toUnit; + const float transparency = 1.0F - static_cast<float>(lineColor.a) * toUnit; + + lineMaterial->diffuseColor.setValue(color); + lineMaterial->ambientColor.setValue(color); + lineMaterial->transparency.setValue(transparency); + + if (element.lineWidth > 0.0F) + { + lineStyle->lineWidth.setValue(element.lineWidth); + } + else + { + lineStyle->style = SoDrawStyleElement::INVISIBLE; + } + + const int pointSize = static_cast<int>(element.points.size()); + lineSet->numVertices.set1Value(0, pointSize); + + return true; + } +} // namespace armarx::viz::coin \ No newline at end of file diff --git a/source/RobotAPI/components/ArViz/Coin/VisualizationPath.h b/source/RobotAPI/components/ArViz/Coin/VisualizationPath.h new file mode 100644 index 0000000000000000000000000000000000000000..e1e446bbe66bc49a6d0c4bdf1999c7f0615f06ec --- /dev/null +++ b/source/RobotAPI/components/ArViz/Coin/VisualizationPath.h @@ -0,0 +1,47 @@ +/* + * 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/>. + * + * @author Fabian Reister ( fabian dot reister at kit dot edu ) + * @date 2021 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#pragma once + +#include "ElementVisualizer.h" + +#include <RobotAPI/interface/ArViz/Elements.h> + +class SoCoordinate3; +class SoDrawStyle; +class SoLineSet; + +namespace armarx::viz::coin +{ + struct VisualizationPath : TypedElementVisualization<SoSeparator> + { + using ElementType = data::ElementPath; + + VisualizationPath(); + + bool update(ElementType const& element); + + SoCoordinate3* coordinate3; + SoDrawStyle* lineStyle; + SoLineSet* lineSet; + SoMaterial* lineMaterial; + }; +} // namespace armarx::viz::coin diff --git a/source/RobotAPI/interface/ArViz/Elements.ice b/source/RobotAPI/interface/ArViz/Elements.ice index 0adf0413b30d5985851b86dab12580d0a314acbe..1c00dd4e630208a79852ea3d18d96da8a501f7d0 100644 --- a/source/RobotAPI/interface/ArViz/Elements.ice +++ b/source/RobotAPI/interface/ArViz/Elements.ice @@ -100,6 +100,14 @@ module data float lineWidth = 0.0f; }; + class ElementPath extends Element + { + Vector3fSeq points; + + Color lineColor; + float lineWidth = 10.0f; + }; + class ElementArrow extends Element { float length = 100.0f; diff --git a/source/RobotAPI/interface/units/RobotUnit/NJointTaskSpaceDMPController.ice b/source/RobotAPI/interface/units/RobotUnit/NJointTaskSpaceDMPController.ice index 93b018801eb5e7f6b870e06b914798d511dc5780..d39e94c87ce0ea5d5ed5b21e252d31f1e2ca41f9 100644 --- a/source/RobotAPI/interface/units/RobotUnit/NJointTaskSpaceDMPController.ice +++ b/source/RobotAPI/interface/units/RobotUnit/NJointTaskSpaceDMPController.ice @@ -325,6 +325,7 @@ module armarx { void learnDMPFromFiles(Ice::StringSeq trajfiles); void learnJointDMPFromFiles(string jointTrajFile, Ice::FloatSeq currentJVS); + void setUseNullSpaceJointDMP(bool enable); bool isFinished(); void runDMP(Ice::DoubleSeq goals); @@ -332,6 +333,7 @@ module armarx void setViaPoints(double canVal, Ice::DoubleSeq point); void setGoals(Ice::DoubleSeq goals); + void setDefaultNullSpaceJointValues(Eigen::VectorXf jointValues); double getVirtualTime(); diff --git a/source/RobotAPI/libraries/RobotAPINJointControllers/DMPController/NJointTaskSpaceImpedanceDMPController.cpp b/source/RobotAPI/libraries/RobotAPINJointControllers/DMPController/NJointTaskSpaceImpedanceDMPController.cpp index 65da4d862d7696bccaca2b68e5576777e722d54d..7e9acde0bdc18f3bd937f5972ce0081727aabc98 100644 --- a/source/RobotAPI/libraries/RobotAPINJointControllers/DMPController/NJointTaskSpaceImpedanceDMPController.cpp +++ b/source/RobotAPI/libraries/RobotAPINJointControllers/DMPController/NJointTaskSpaceImpedanceDMPController.cpp @@ -4,9 +4,12 @@ namespace armarx { - NJointControllerRegistration<NJointTaskSpaceImpedanceDMPController> registrationControllerNJointTaskSpaceImpedanceDMPController("NJointTaskSpaceImpedanceDMPController"); + NJointControllerRegistration<NJointTaskSpaceImpedanceDMPController> registrationControllerNJointTaskSpaceImpedanceDMPController( + "NJointTaskSpaceImpedanceDMPController"); - NJointTaskSpaceImpedanceDMPController::NJointTaskSpaceImpedanceDMPController(const RobotUnitPtr& robotUnit, const armarx::NJointControllerConfigPtr& config, const VirtualRobot::RobotPtr&) + NJointTaskSpaceImpedanceDMPController::NJointTaskSpaceImpedanceDMPController(const RobotUnitPtr& robotUnit, + const armarx::NJointControllerConfigPtr& config, + const VirtualRobot::RobotPtr&) { ARMARX_INFO << "creating impedance dmp controller"; cfg = NJointTaskSpaceImpedanceDMPControllerConfigPtr::dynamicCast(config); @@ -37,8 +40,9 @@ namespace armarx positionSensors.push_back(positionSensor); }; - tcp = rns->getTCP(); - ik.reset(new VirtualRobot::DifferentialIK(rns, rtGetRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped)); + tcp = rns->getTCP(); + ik.reset(new VirtualRobot::DifferentialIK(rns, rtGetRobot()->getRootNode(), + VirtualRobot::JacobiProvider::eSVDDamped)); numOfJoints = targets.size(); // set DMP TaskSpaceDMPControllerConfig taskSpaceDMPConfig; @@ -65,14 +69,15 @@ namespace armarx isNullSpaceJointDMPLearned = false; - defaultNullSpaceJointValues.resize(targets.size()); + Eigen::VectorXf nullspaceValues(targets.size()); + ARMARX_CHECK_EQUAL(cfg->defaultNullSpaceJointValues.size(), targets.size()); for (size_t i = 0; i < targets.size(); ++i) { - defaultNullSpaceJointValues(i) = cfg->defaultNullSpaceJointValues.at(i); + nullspaceValues(i) = cfg->defaultNullSpaceJointValues.at(i); } - + defaultNullSpaceJointValues.reinitAllBuffers(nullspaceValues); Eigen::Vector3f kpos(cfg->Kpos[0], cfg->Kpos[1], cfg->Kpos[2]); Eigen::Vector3f dpos(cfg->Dpos[0], cfg->Dpos[1], cfg->Dpos[2]); @@ -126,7 +131,7 @@ namespace armarx initData.targetPose = tcp->getPoseInRootFrame(); initData.targetVel.resize(6); initData.targetVel.setZero(); - initData.desiredNullSpaceJointValues = defaultNullSpaceJointValues; + initData.desiredNullSpaceJointValues = defaultNullSpaceJointValues.getUpToDateReadBuffer(); reinitTripleBuffer(initData); @@ -154,8 +159,8 @@ namespace armarx if (!started) { - LockGuardType guard {controlDataMutex}; - getWriterControlStruct().desiredNullSpaceJointValues = defaultNullSpaceJointValues; + LockGuardType guard{controlDataMutex}; + getWriterControlStruct().desiredNullSpaceJointValues = defaultNullSpaceJointValues.getUpToDateReadBuffer(); getWriterControlStruct().targetVel.setZero(6); getWriterControlStruct().targetPose = currentPose; getWriterControlStruct().canVal = 1.0; @@ -167,8 +172,8 @@ namespace armarx if (stopped) { - LockGuardType guard {controlDataMutex}; - getWriterControlStruct().desiredNullSpaceJointValues = defaultNullSpaceJointValues; + LockGuardType guard{controlDataMutex}; + getWriterControlStruct().desiredNullSpaceJointValues = defaultNullSpaceJointValues.getUpToDateReadBuffer(); getWriterControlStruct().targetVel.setZero(6); getWriterControlStruct().targetPose = oldPose; getWriterControlStruct().canVal = dmpCtrl->canVal; @@ -180,7 +185,7 @@ namespace armarx if (dmpCtrl->canVal < 1e-8) { finished = true; - LockGuardType guard {controlDataMutex}; + LockGuardType guard{controlDataMutex}; getWriterControlStruct().targetVel.setZero(); writeControlStruct(); return; @@ -192,7 +197,10 @@ namespace armarx if (useNullSpaceJointDMP && isNullSpaceJointDMPLearned) { DMP::DVec targetJointState; - currentJointState = nullSpaceJointDMPPtr->calculateDirectlyVelocity(currentJointState, dmpCtrl->canVal / timeDuration, deltaT / timeDuration, targetJointState); + currentJointState = nullSpaceJointDMPPtr->calculateDirectlyVelocity(currentJointState, + dmpCtrl->canVal / timeDuration, + deltaT / timeDuration, + targetJointState); if (targetJointState.size() == jointNames.size()) { @@ -203,15 +211,15 @@ namespace armarx } else { - desiredNullSpaceJointValues = defaultNullSpaceJointValues; + desiredNullSpaceJointValues = defaultNullSpaceJointValues.getUpToDateReadBuffer(); } } else { - desiredNullSpaceJointValues = defaultNullSpaceJointValues; + desiredNullSpaceJointValues = defaultNullSpaceJointValues.getUpToDateReadBuffer(); } - LockGuardType guard {controlDataMutex}; + LockGuardType guard{controlDataMutex}; getWriterControlStruct().desiredNullSpaceJointValues = desiredNullSpaceJointValues; getWriterControlStruct().targetVel = dmpCtrl->getTargetVelocity(); getWriterControlStruct().targetPose = dmpCtrl->getTargetPoseMat(); @@ -223,7 +231,8 @@ namespace armarx } } - void NJointTaskSpaceImpedanceDMPController::rtRun(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration) + void NJointTaskSpaceImpedanceDMPController::rtRun(const IceUtil::Time& sensorValuesTimestamp, + const IceUtil::Time& timeSinceLastIteration) { double deltaT = timeSinceLastIteration.toSecondsDouble(); @@ -261,7 +270,7 @@ namespace armarx firstRun = false; targetPose = currentPose; targetVel.setZero(6); - desiredNullSpaceJointValues = defaultNullSpaceJointValues; + desiredNullSpaceJointValues = defaultNullSpaceJointValues.getUpToDateReadBuffer(); } else { @@ -280,25 +289,28 @@ namespace armarx Eigen::Vector3f targetTCPLinearVelocity; targetTCPLinearVelocity << 0.001 * targetVel(0), 0.001 * targetVel(1), 0.001 * targetVel(2); Eigen::Vector3f currentTCPLinearVelocity; - currentTCPLinearVelocity << 0.001 * currentTwist(0), 0.001 * currentTwist(1), 0.001 * currentTwist(2); + currentTCPLinearVelocity << 0.001 * currentTwist(0), 0.001 * currentTwist(1), 0.001 * currentTwist(2); Eigen::Vector3f currentTCPPosition = currentPose.block<3, 1>(0, 3); Eigen::Vector3f desiredPosition = targetPose.block<3, 1>(0, 3); - Eigen::Vector3f tcpDesiredForce = 0.001 * kpos.cwiseProduct(desiredPosition - currentTCPPosition) + dpos.cwiseProduct(targetTCPLinearVelocity - currentTCPLinearVelocity); + Eigen::Vector3f tcpDesiredForce = 0.001 * kpos.cwiseProduct(desiredPosition - currentTCPPosition) + + dpos.cwiseProduct(targetTCPLinearVelocity - currentTCPLinearVelocity); Eigen::Vector3f currentTCPAngularVelocity; - currentTCPAngularVelocity << currentTwist(3), currentTwist(4), currentTwist(5); + currentTCPAngularVelocity << currentTwist(3), currentTwist(4), currentTwist(5); Eigen::Matrix3f currentRotMat = currentPose.block<3, 3>(0, 0); Eigen::Matrix3f diffMat = targetPose.block<3, 3>(0, 0) * currentRotMat.inverse(); Eigen::Vector3f rpy = VirtualRobot::MathTools::eigen3f2rpy(diffMat); Eigen::Vector3f tcpDesiredTorque = kori.cwiseProduct(rpy) - dori.cwiseProduct(currentTCPAngularVelocity); - jointControlWrench << tcpDesiredForce, tcpDesiredTorque; + jointControlWrench << tcpDesiredForce, tcpDesiredTorque; } Eigen::MatrixXf I = Eigen::MatrixXf::Identity(targets.size(), targets.size()); - Eigen::VectorXf nullspaceTorque = knull.cwiseProduct(desiredNullSpaceJointValues - qpos) - dnull.cwiseProduct(qvel); + Eigen::VectorXf nullspaceTorque = + knull.cwiseProduct(desiredNullSpaceJointValues - qpos) - dnull.cwiseProduct(qvel); Eigen::MatrixXf jtpinv = ik->computePseudoInverseJacobianMatrix(jacobi.transpose(), 2.0); - Eigen::VectorXf jointDesiredTorques = jacobi.transpose() * jointControlWrench + (I - jacobi.transpose() * jtpinv) * nullspaceTorque; + Eigen::VectorXf jointDesiredTorques = + jacobi.transpose() * jointControlWrench + (I - jacobi.transpose() * jtpinv) * nullspaceTorque; @@ -316,7 +328,7 @@ namespace armarx desiredTorque = 0; } - desiredTorque = (desiredTorque > torqueLimit) ? torqueLimit : desiredTorque; + desiredTorque = (desiredTorque > torqueLimit) ? torqueLimit : desiredTorque; desiredTorque = (desiredTorque < -torqueLimit) ? -torqueLimit : desiredTorque; debugOutputData.getWriteBuffer().desired_torques[jointNames[i]] = jointDesiredTorques(i); @@ -325,7 +337,8 @@ namespace armarx targets.at(i)->torque = desiredTorque; if (!targets.at(i)->isValid()) { - ARMARX_INFO << deactivateSpam(1) << "Torque controller target is invalid - setting to zero! set value: " << targets.at(i)->torque; + ARMARX_INFO << deactivateSpam(1) << "Torque controller target is invalid - setting to zero! set value: " + << targets.at(i)->torque; targets.at(i)->torque = 0.0f; } } @@ -371,7 +384,8 @@ namespace armarx ARMARX_INFO << "Learned DMP ... "; } - void NJointTaskSpaceImpedanceDMPController::setViaPoints(Ice::Double u, const Ice::DoubleSeq& viapoint, const Ice::Current&) + void NJointTaskSpaceImpedanceDMPController::setViaPoints(Ice::Double u, const Ice::DoubleSeq& viapoint, + const Ice::Current&) { LockGuardType guard(controllerMutex); ARMARX_INFO << "setting via points "; @@ -385,9 +399,11 @@ namespace armarx } - void NJointTaskSpaceImpedanceDMPController::learnJointDMPFromFiles(const std::string& fileName, const Ice::FloatSeq& currentJVS, const Ice::Current&) + void NJointTaskSpaceImpedanceDMPController::learnJointDMPFromFiles(const std::string& fileName, + const Ice::FloatSeq& currentJVS, + const Ice::Current&) { - DMP::Vec<DMP::SampledTrajectoryV2 > trajs; + DMP::Vec<DMP::SampledTrajectoryV2> trajs; DMP::DVec ratios; DMP::SampledTrajectoryV2 traj; traj.readFromCSVFile(fileName); @@ -439,8 +455,14 @@ namespace armarx stopped = false; } + void NJointTaskSpaceImpedanceDMPController::setUseNullSpaceJointDMP(bool enable, const Ice::Current&) + { + useNullSpaceJointDMP = enable; + } + - void NJointTaskSpaceImpedanceDMPController::runDMPWithTime(const Ice::DoubleSeq& goals, Ice::Double timeDuration, const Ice::Current&) + void NJointTaskSpaceImpedanceDMPController::runDMPWithTime(const Ice::DoubleSeq& goals, Ice::Double timeDuration, + const Ice::Current&) { firstRun = true; while (firstRun) @@ -490,8 +512,8 @@ namespace armarx } - - void NJointTaskSpaceImpedanceDMPController::onPublish(const SensorAndControl&, const DebugDrawerInterfacePrx&, const DebugObserverInterfacePrx& debugObs) + void NJointTaskSpaceImpedanceDMPController::onPublish(const SensorAndControl&, const DebugDrawerInterfacePrx&, + const DebugObserverInterfacePrx& debugObs) { StringVariantBaseMap datafields; auto values = debugOutputData.getUpToDateReadBuffer().desired_torques; @@ -585,7 +607,7 @@ namespace armarx void NJointTaskSpaceImpedanceDMPController::removeAllViaPoints(const Ice::Current&) { - LockGuardType guard {controllerMutex}; + LockGuardType guard{controllerMutex}; ARMARX_INFO << "setting via points "; dmpCtrl->removeAllViaPoints(); } @@ -626,5 +648,14 @@ namespace armarx } + void NJointTaskSpaceImpedanceDMPController::setDefaultNullSpaceJointValues(const Eigen::VectorXf& jointValues, + const Ice::Current&) + { + ARMARX_CHECK_EQUAL(jointValues.size(), targets.size()); + defaultNullSpaceJointValues.getWriteBuffer() = jointValues; + defaultNullSpaceJointValues.commitWrite(); + + } + } diff --git a/source/RobotAPI/libraries/RobotAPINJointControllers/DMPController/NJointTaskSpaceImpedanceDMPController.h b/source/RobotAPI/libraries/RobotAPINJointControllers/DMPController/NJointTaskSpaceImpedanceDMPController.h index 1b49c99634870147df440d88709f828c0e074872..ea8cef187de6296e07eeb270e4ca5ac2ad7b78f6 100644 --- a/source/RobotAPI/libraries/RobotAPINJointControllers/DMPController/NJointTaskSpaceImpedanceDMPController.h +++ b/source/RobotAPI/libraries/RobotAPINJointControllers/DMPController/NJointTaskSpaceImpedanceDMPController.h @@ -42,51 +42,53 @@ namespace armarx NJointTaskSpaceImpedanceDMPController(const RobotUnitPtr& robotUnit, const NJointControllerConfigPtr& config, const VirtualRobot::RobotPtr&); // NJointControllerInterface interface - std::string getClassName(const Ice::Current&) const; + std::string getClassName(const Ice::Current&) const override; // NJointController interface - void rtRun(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration); + void rtRun(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration) override; // NJointTaskSpaceImpedanceDMPControllerInterface interface - void learnDMPFromFiles(const Ice::StringSeq& fileNames, const Ice::Current&); - bool isFinished(const Ice::Current&) + void learnDMPFromFiles(const Ice::StringSeq& fileNames, const Ice::Current&) override; + bool isFinished(const Ice::Current&) override { return finished; } - void setViaPoints(Ice::Double u, const Ice::DoubleSeq& viapoint, const Ice::Current&); - void setGoals(const Ice::DoubleSeq& goals, const Ice::Current&); + void setViaPoints(Ice::Double u, const Ice::DoubleSeq& viapoint, const Ice::Current&) override; + void setGoals(const Ice::DoubleSeq& goals, const Ice::Current&) override; - void learnJointDMPFromFiles(const std::string& fileName, const Ice::FloatSeq& currentJVS, const Ice::Current&); - void runDMP(const Ice::DoubleSeq& goals, const Ice::Current&); - void runDMPWithTime(const Ice::DoubleSeq& goals, Ice::Double timeDuration, const Ice::Current&); + void learnJointDMPFromFiles(const std::string& fileName, const Ice::FloatSeq& currentJVS, const Ice::Current&) override; + void runDMP(const Ice::DoubleSeq& goals, const Ice::Current&) override; + void runDMPWithTime(const Ice::DoubleSeq& goals, Ice::Double timeDuration, const Ice::Current&) override; - Ice::Double getVirtualTime(const Ice::Current&) + Ice::Double getVirtualTime(const Ice::Current&) override { return dmpCtrl->canVal; } - void stopDMP(const Ice::Current&); - void resumeDMP(const Ice::Current&); - void resetDMP(const Ice::Current&); + void stopDMP(const Ice::Current&) override; + void resumeDMP(const Ice::Current&) override; + void resetDMP(const Ice::Current&) override; - void setMPWeights(const DoubleSeqSeq& weights, const Ice::Current&); - DoubleSeqSeq getMPWeights(const Ice::Current&); + void setMPWeights(const DoubleSeqSeq& weights, const Ice::Current&) override; + DoubleSeqSeq getMPWeights(const Ice::Current&) override; void removeAllViaPoints(const Ice::Current&) override; void setLinearVelocityKd(const Ice::FloatSeq& kd, const Ice::Current&) override; - void setLinearVelocityKp(const Ice::FloatSeq& kp, const Ice::Current&)override; - void setAngularVelocityKd(const Ice::FloatSeq& kd, const Ice::Current&)override; - void setAngularVelocityKp(const Ice::FloatSeq& kp, const Ice::Current&)override; + void setLinearVelocityKp(const Ice::FloatSeq& kp, const Ice::Current&) override; + void setAngularVelocityKd(const Ice::FloatSeq& kd, const Ice::Current&) override; + void setAngularVelocityKp(const Ice::FloatSeq& kp, const Ice::Current&) override; + void setUseNullSpaceJointDMP(bool enable, const Ice::Current&) override; + void setDefaultNullSpaceJointValues(const Eigen::VectorXf& jointValues, const Ice::Current&) override; protected: - virtual void onPublish(const SensorAndControl&, const DebugDrawerInterfacePrx&, const DebugObserverInterfacePrx&); + virtual void onPublish(const SensorAndControl&, const DebugDrawerInterfacePrx&, const DebugObserverInterfacePrx&) override; - void onInitNJointController(); - void onDisconnectNJointController(); + void onInitNJointController() override; + void onDisconnectNJointController() override; void controllerRun(); private: @@ -190,11 +192,11 @@ namespace armarx Eigen::VectorXf dnull; int numOfJoints; - bool useNullSpaceJointDMP; + std::atomic_bool useNullSpaceJointDMP; bool isNullSpaceJointDMPLearned; - Eigen::VectorXf defaultNullSpaceJointValues; + armarx::TripleBuffer<Eigen::VectorXf> defaultNullSpaceJointValues; std::vector<std::string> jointNames; mutable MutexType controllerMutex; PeriodicTask<NJointTaskSpaceImpedanceDMPController>::pointer_type controllerTask; diff --git a/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.cpp b/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.cpp index c8db83835ccc53f21e416b723745892a1455f801..5a3a4a0d4abd221dd9ce8385fbce98a747f36c09 100644 --- a/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.cpp +++ b/source/RobotAPI/libraries/armem_robot_state/common/localization/TransformHelper.cpp @@ -284,14 +284,17 @@ namespace armarx::armem::common::robot_state::localization std::vector<::armarx::armem::robot_state::Transform> transforms; transforms.reserve(entity.history().size()); - const auto entitySnapshots = simox::alg::get_values(entity.history()); + // const auto entitySnapshots = simox::alg::get_values(entity.history()); + + const std::vector<wm::EntitySnapshot> entitySnapshots = {entity.getLatestSnapshot()}; + std::transform( entitySnapshots.begin(), entitySnapshots.end(), std::back_inserter(transforms), - [](const auto & entity) + [](const auto & entitySnapshot) { - return convertEntityToTransform(entity.getInstance(0)); + return convertEntityToTransform(entitySnapshot.getInstance(0)); }); ARMARX_DEBUG << "obtaining transform"; diff --git a/source/RobotAPI/libraries/core/CartesianVelocityController.cpp b/source/RobotAPI/libraries/core/CartesianVelocityController.cpp index f140f9512bcb990a82e50ed3eb271536817d4d88..9527835a6dd48107f5e11846ec882d30b056c54a 100644 --- a/source/RobotAPI/libraries/core/CartesianVelocityController.cpp +++ b/source/RobotAPI/libraries/core/CartesianVelocityController.cpp @@ -57,6 +57,11 @@ void CartesianVelocityController::calculateJacobis(VirtualRobot::IKSolver::Carte _jacobiWithCosts(r, c) = jacobi(r, c) / _jointCosts(c); } } + auto svd = Eigen::JacobiSVD(_jacobiWithCosts, Eigen::ComputeThinU | Eigen::ComputeThinV); + auto sv = svd.singularValues(); + double minSigVal = sv(sv.rows() - 1, sv.cols() - 1); + double damping = minSigVal < 1e-2 ? 1e-2 : 1e-8; + ik->setDampedSvdLambda(damping); _inv = ik->computePseudoInverseJacobianMatrix(_jacobiWithCosts, ik->getJacobiRegularization(mode)); } @@ -267,6 +272,11 @@ bool CartesianVelocityController::clampJacobiAtJointLimits(VirtualRobot::IKSolve } if (modifiedJacobi) { + auto svd = Eigen::JacobiSVD(jacobi, Eigen::ComputeThinU | Eigen::ComputeThinV); + auto sv = svd.singularValues(); + double minSigVal = sv(sv.rows() - 1, sv.cols() - 1); + double damping = minSigVal < 1e-2 ? 1e-2 : 1e-8; + ik->setDampedSvdLambda(damping); inv = ik->computePseudoInverseJacobianMatrix(jacobi, ik->getJacobiRegularization(mode)); }