diff --git a/source/RobotAPI/interface/CMakeLists.txt b/source/RobotAPI/interface/CMakeLists.txt index 978fd19bcd408f00974daaa0060fc2b3ff8853d4..32308c8a90c3ed3bb0a5f85e6de9df50c2354586 100644 --- a/source/RobotAPI/interface/CMakeLists.txt +++ b/source/RobotAPI/interface/CMakeLists.txt @@ -52,6 +52,9 @@ set(SLICE_FILES units/RobotUnit/NJointCartesianTorqueController.ice units/RobotUnit/NJointCartesianActiveImpedanceController.ice units/RobotUnit/NJointCartesianVelocityControllerWithRamp.ice + + units/RobotUnit/NJointGripperController.ice + units/RobotUnit/RobotUnitInterface.ice units/RobotUnit/NJointJointSpaceDMPController.ice diff --git a/source/RobotAPI/interface/units/RobotUnit/NJointGripperController.ice b/source/RobotAPI/interface/units/RobotUnit/NJointGripperController.ice new file mode 100644 index 0000000000000000000000000000000000000000..1b79c59ba77f1987ad3c9fc2e912132431741f25 --- /dev/null +++ b/source/RobotAPI/interface/units/RobotUnit/NJointGripperController.ice @@ -0,0 +1,39 @@ +/* + * 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 RobotAPI::NJointControllerInterface + * @author Mirko Waechter ( mirko dot waechter at kit dot edu ) + * @date 2017 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#pragma once + +#include <RobotAPI/interface/units/RobotUnit/NJointController.ice> +#include <RobotAPI/interface/core/Trajectory.ice> + +module armarx +{ + + class NJointGripperZeroTorqueControllerConfig extends NJointControllerConfig + { + string nodeSetName; + }; + + interface NJointGripperZeroTorqueControllerInterface extends NJointControllerInterface + { + }; +}; diff --git a/source/RobotAPI/interface/units/RobotUnit/NJointTaskSpaceDMPController.ice b/source/RobotAPI/interface/units/RobotUnit/NJointTaskSpaceDMPController.ice index d3d62e88d8e4bb28a2b3da115ed570abaa308c71..e4af46f9e7fb9115bf9389e76c2bb877d4f61f0e 100644 --- a/source/RobotAPI/interface/units/RobotUnit/NJointTaskSpaceDMPController.ice +++ b/source/RobotAPI/interface/units/RobotUnit/NJointTaskSpaceDMPController.ice @@ -65,13 +65,16 @@ module armarx double maxLinearVel; double maxAngularVel; - + double maxJointVelocity; string debugName; float Kp_LinearVel; float Kd_LinearVel; float Kp_AngularVel; float Kd_AngularVel; + + float pos_filter; + float vel_filter; }; diff --git a/source/RobotAPI/libraries/KITGripperEtherCAT/KITGripperBasisBoard/KITGripperBasisBoardData.cpp b/source/RobotAPI/libraries/KITGripperEtherCAT/KITGripperBasisBoard/KITGripperBasisBoardData.cpp index de73c55fc27451cb15d1ecec4d80d06f4a9c23d1..7cc4f276201013cbcdc6296863ae2e1800b8979f 100644 --- a/source/RobotAPI/libraries/KITGripperEtherCAT/KITGripperBasisBoard/KITGripperBasisBoardData.cpp +++ b/source/RobotAPI/libraries/KITGripperEtherCAT/KITGripperBasisBoard/KITGripperBasisBoardData.cpp @@ -103,7 +103,7 @@ namespace armarx if (d.getSiblingControlActorIndex() >= 0) { auto& d2 = actorData.at(d.getSiblingControlActorIndex()); - ARMARX_IMPORTANT << "decoupling factor: " << d.parallelGripperDecouplingFactor; + // ARMARX_IMPORTANT << "decoupling factor: " << d.parallelGripperDecouplingFactor; d.adjustedRelativePosition = d.relativePosition.value + d2->relativePosition.value * d.parallelGripperDecouplingFactor; } diff --git a/source/RobotAPI/libraries/RobotAPINJointControllers/CMakeLists.txt b/source/RobotAPI/libraries/RobotAPINJointControllers/CMakeLists.txt index 74ef54267526a33c4082dc468ffe885985253d94..c2da980f612073bbf9db3f885b26edca57b16367 100644 --- a/source/RobotAPI/libraries/RobotAPINJointControllers/CMakeLists.txt +++ b/source/RobotAPI/libraries/RobotAPINJointControllers/CMakeLists.txt @@ -27,9 +27,11 @@ set(LIBS RobotAPIInterfaces ArmarXCoreObservers ArmarXCoreStatechart ArmarXCoreE ) set(LIB_FILES + GripperController/NJointGripperZeroTorqueController.cpp ) set(LIB_HEADERS + GripperController/NJointGripperZeroTorqueController.h ) diff --git a/source/RobotAPI/libraries/RobotAPINJointControllers/DMPController/NJointTSDMPController.cpp b/source/RobotAPI/libraries/RobotAPINJointControllers/DMPController/NJointTSDMPController.cpp index b291966f1f168da4b59f32611f81af9dcd5d8934..a8fc9987885cae9cd0d5c2a89a61eb7a25889794 100644 --- a/source/RobotAPI/libraries/RobotAPINJointControllers/DMPController/NJointTSDMPController.cpp +++ b/source/RobotAPI/libraries/RobotAPINJointControllers/DMPController/NJointTSDMPController.cpp @@ -19,21 +19,14 @@ namespace armarx const SensorValueBase* sv = useSensorValue(jointName); targets.push_back(ct->asA<ControlTarget1DoFActuatorVelocity>()); - const SensorValue1DoFActuatorTorque* torqueSensor = sv->asA<SensorValue1DoFActuatorTorque>(); + // const SensorValue1DoFActuatorTorque* torqueSensor = sv->asA<SensorValue1DoFActuatorTorque>(); + // const SensorValue1DoFGravityTorque* gravityTorqueSensor = sv->asA<SensorValue1DoFGravityTorque>(); + const SensorValue1DoFActuatorVelocity* velocitySensor = sv->asA<SensorValue1DoFActuatorVelocity>(); - const SensorValue1DoFGravityTorque* gravityTorqueSensor = sv->asA<SensorValue1DoFGravityTorque>(); const SensorValue1DoFActuatorPosition* positionSensor = sv->asA<SensorValue1DoFActuatorPosition>(); - if (!torqueSensor) - { - ARMARX_WARNING << "No Torque sensor available for " << jointName; - } - if (!gravityTorqueSensor) - { - ARMARX_WARNING << "No Gravity Torque sensor available for " << jointName; - } - torqueSensors.push_back(torqueSensor); - gravityTorqueSensors.push_back(gravityTorqueSensor); + // torqueSensors.push_back(torqueSensor); + // gravityTorqueSensors.push_back(gravityTorqueSensor); velocitySensors.push_back(velocitySensor); positionSensors.push_back(positionSensor); }; @@ -99,6 +92,13 @@ namespace armarx DpF = cfg->Kd_LinearVel; DoF = cfg->Kd_AngularVel; + filtered_qvel.setZero(targets.size()); + vel_filter_factor = cfg->vel_filter; + + filtered_position.setZero(); + pos_filter_factor = cfg->pos_filter; + + firstRun = true; } std::string NJointTSDMPController::getClassName(const Ice::Current&) const @@ -118,15 +118,19 @@ namespace armarx taskSpaceDMPController->flow(deltaT, currentPose, currentTwist); + if (taskSpaceDMPController->canVal < 1e-8) { finished = true; } targetVels = taskSpaceDMPController->getTargetVelocity(); - - targetPose = taskSpaceDMPController->getTargetPoseMat(); std::vector<double> targetState = taskSpaceDMPController->getTargetPose(); + + // ARMARX_IMPORTANT << "CanVal: " << taskSpaceDMPController->canVal; + // ARMARX_IMPORTANT << "targetVels: " << targetVels; + // ARMARX_IMPORTANT << "targetPose: " << targetPose; + debugOutputData.getWriteBuffer().latestTargetVelocities["x_vel"] = targetVels(0); debugOutputData.getWriteBuffer().latestTargetVelocities["y_vel"] = targetVels(1); debugOutputData.getWriteBuffer().latestTargetVelocities["z_vel"] = targetVels(2); @@ -172,6 +176,8 @@ namespace armarx void NJointTSDMPController::rtRun(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration) { Eigen::Matrix4f currentPose = tcp->getPoseInRootFrame(); + + double deltaT = timeSinceLastIteration.toSecondsDouble(); Eigen::MatrixXf jacobi = ik->getJacobianMatrix(tcp, VirtualRobot::IKSolver::CartesianSelection::All); @@ -183,7 +189,8 @@ namespace armarx qvel(i) = velocitySensors[i]->velocity; } - Eigen::VectorXf tcptwist = jacobi * qvel; + filtered_qvel = (1 - vel_filter_factor) * filtered_qvel + vel_filter_factor * qvel; + Eigen::VectorXf tcptwist = jacobi * filtered_qvel; controllerSensorData.getWriteBuffer().currentPose = currentPose; controllerSensorData.getWriteBuffer().currentTwist = tcptwist; @@ -201,14 +208,23 @@ namespace armarx Eigen::Matrix3f diffMat = targetPose.block<3, 3>(0, 0) * currentPose.block<3, 3>(0, 0).inverse(); Eigen::Vector3f errorRPY = VirtualRobot::MathTools::eigen3f2rpy(diffMat); - + if (firstRun) + { + filtered_position = currentPose.block<3, 1>(0, 3); + firstRun = false; + } + else + { + filtered_position = (1 - pos_filter_factor) * filtered_position + pos_filter_factor * currentPose.block<3, 1>(0, 3); + } Eigen::VectorXf rtTargetVel; rtTargetVel.resize(6); - rtTargetVel.block<3, 1>(0, 0) = KpF * (targetPose.block<3, 1>(0, 3) - currentPose.block<3, 1>(0, 3)) + DpF * (targetVel.block<3, 1>(0, 0) - tcptwist.block<3, 1>(0, 0)); + rtTargetVel.block<3, 1>(0, 0) = KpF * (targetPose.block<3, 1>(0, 3) - filtered_position) + DpF * (targetVel.block<3, 1>(0, 0) - tcptwist.block<3, 1>(0, 0)); rtTargetVel.block<3, 1>(3, 0) = KoF * errorRPY + DoF * (targetVel.block<3, 1>(3, 0) - tcptwist.block<3, 1>(3, 0)); // rtTargetVel = targetVel; + float normLinearVelocity = rtTargetVel.block<3, 1>(0, 0).norm(); if (normLinearVelocity > cfg->maxLinearVel) { @@ -267,16 +283,16 @@ namespace armarx for (size_t i = 0; i < tcpController->rns->getSize(); i++) { jnv(i) += rtGetControlStruct().nullspaceJointVelocities.at(i); - if (torqueSensors.at(i) && gravityTorqueSensors.at(i) && rtGetControlStruct().torqueKp.at(i) != 0) - { - torquePIDs.at(i).Kp = rtGetControlStruct().torqueKp.at(i); - torquePIDs.at(i).Kd = rtGetControlStruct().torqueKd.at(i); - jnv(i) += torquePIDs.at(i).update(deltaT, torqueSensors.at(i)->torque - gravityTorqueSensors.at(i)->gravityTorque); - } - else - { - torquePIDs.at(i).lastError = 0; - } + // if (torqueSensors.at(i) && gravityTorqueSensors.at(i) && rtGetControlStruct().torqueKp.at(i) != 0) + // { + // torquePIDs.at(i).Kp = rtGetControlStruct().torqueKp.at(i); + // torquePIDs.at(i).Kd = rtGetControlStruct().torqueKd.at(i); + // jnv(i) += torquePIDs.at(i).update(deltaT, torqueSensors.at(i)->torque - gravityTorqueSensors.at(i)->gravityTorque); + // } + // else + // { + // torquePIDs.at(i).lastError = 0; + // } } Eigen::VectorXf jointTargetVelocities = tcpController->calculate(x, jnv, mode); @@ -285,10 +301,11 @@ namespace armarx for (size_t i = 0; i < targets.size(); ++i) { targets.at(i)->velocity = jointTargetVelocities(i); - if (!targets.at(i)->isValid()) + + if (!targets.at(i)->isValid() || fabs(targets.at(i)->velocity) > cfg->maxJointVelocity) { ARMARX_IMPORTANT << deactivateSpam(1, std::to_string(i)) - << "Torque controller target is invalid - setting to zero! set value: " << targets.at(i)->velocity; + << "Velocity controller target is invalid - setting to zero! set value: " << targets.at(i)->velocity; targets.at(i)->velocity = 0.0f; } } diff --git a/source/RobotAPI/libraries/RobotAPINJointControllers/DMPController/NJointTSDMPController.h b/source/RobotAPI/libraries/RobotAPINJointControllers/DMPController/NJointTSDMPController.h index 68a4f41d1bb1c5bbbb34c28d803ba85f26afd1cc..91fd0b4b6f48df45846e6ca120a86ba207771223 100644 --- a/source/RobotAPI/libraries/RobotAPINJointControllers/DMPController/NJointTSDMPController.h +++ b/source/RobotAPI/libraries/RobotAPINJointControllers/DMPController/NJointTSDMPController.h @@ -163,6 +163,12 @@ namespace armarx std::string debugName; + Eigen::VectorXf filtered_qvel; + Eigen::Vector3f filtered_position; + float vel_filter_factor; + float pos_filter_factor; + bool firstRun; + float KpF; float DpF; float KoF; diff --git a/source/RobotAPI/libraries/RobotAPINJointControllers/GripperController/NJointGripperZeroTorqueController.cpp b/source/RobotAPI/libraries/RobotAPINJointControllers/GripperController/NJointGripperZeroTorqueController.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4173f0942a1e188e148d18c6ead9b0a0ab32b4f7 --- /dev/null +++ b/source/RobotAPI/libraries/RobotAPINJointControllers/GripperController/NJointGripperZeroTorqueController.cpp @@ -0,0 +1,57 @@ +#include "NJointGripperZeroTorqueController.h" +#include <VirtualRobot/RobotNodeSet.h> + +namespace armarx +{ + NJointControllerRegistration<NJointGripperZeroTorqueController> registrationControllerNJointGripperZeroTorqueController("NJointGripperZeroTorqueController"); + + NJointGripperZeroTorqueController::NJointGripperZeroTorqueController(const RobotUnitPtr&, const armarx::NJointControllerConfigPtr& config, const VirtualRobot::RobotPtr&) + { + useSynchronizedRtRobot(); + NJointGripperZeroTorqueControllerConfigPtr cfg = NJointGripperZeroTorqueControllerConfigPtr::dynamicCast(config); + VirtualRobot::RobotNodeSetPtr rns = rtGetRobot()->getRobotNodeSet(cfg->nodeSetName); + + for (size_t i = 0; i < rns->getSize(); ++i) + { + std::string jointName = rns->getNode(i)->getName(); + ControlTargetBase* ct = useControlTarget(jointName, ControlModes::ZeroTorque1DoF); + targets.push_back(ct->asA<ControlTarget1DoFActuatorZeroTorque>()); + }; + } + + std::string NJointGripperZeroTorqueController::getClassName(const Ice::Current&) const + { + return "NJointGripperZeroTorqueController"; + } + + void NJointGripperZeroTorqueController::rtRun(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration) + { + for (size_t i = 0; i < targets.size(); ++i) + { + targets.at(i)->torque = 0; + } + } + + WidgetDescription::WidgetPtr NJointGripperZeroTorqueController::GenerateConfigDescription(const VirtualRobot::RobotPtr & robot, const std::map<std::string, ConstControlDevicePtr> & controlDevices, const std::map<std::string, ConstSensorDevicePtr> &) + { + using namespace armarx::WidgetDescription; + HBoxLayoutPtr layout = new HBoxLayout; + + LabelPtr label = new Label; + label->text = "nodeset name"; + layout->children.emplace_back(label); + + StringComboBoxPtr box = new StringComboBox; + box->defaultIndex = 0; + box->options = robot->getRobotNodeSetNames(); + box->name = "nodeSetName"; + layout->children.emplace_back(box); + + return layout; + } + + NJointGripperZeroTorqueControllerConfigPtr NJointGripperZeroTorqueController::GenerateConfigFromVariants(const StringVariantBaseMap &values) + { + return new NJointGripperZeroTorqueControllerConfig(values.at("nodeSetName")->getString()); + } +} diff --git a/source/RobotAPI/libraries/RobotAPINJointControllers/GripperController/NJointGripperZeroTorqueController.h b/source/RobotAPI/libraries/RobotAPINJointControllers/GripperController/NJointGripperZeroTorqueController.h new file mode 100644 index 0000000000000000000000000000000000000000..f5c6accfc21d19e4bd3854e4c600bbb843d7e5f4 --- /dev/null +++ b/source/RobotAPI/libraries/RobotAPINJointControllers/GripperController/NJointGripperZeroTorqueController.h @@ -0,0 +1,53 @@ + +#pragma once + +#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointController.h> +#include <VirtualRobot/Robot.h> +#include <RobotAPI/components/units/RobotUnit/RobotUnit.h> +#include <RobotAPI/components/units/RobotUnit/ControlTargets/ControlTarget1DoFActuator.h> +#include <RobotAPI/interface/units/RobotUnit/NJointGripperController.h> + + +namespace armarx +{ + + + TYPEDEF_PTRS_HANDLE(NJointGripperZeroTorqueController); + TYPEDEF_PTRS_HANDLE(NJointGripperZeroTorqueControllerControlData); + + + class NJointGripperZeroTorqueControllerControlData + { + }; + + /** + * @brief The NJointGripperZeroTorqueController class + * @ingroup Library-RobotUnit-NJointControllers + */ + class NJointGripperZeroTorqueController : + public NJointControllerWithTripleBuffer<NJointGripperZeroTorqueControllerControlData>, + public NJointGripperZeroTorqueControllerInterface + { + public: + using ConfigPtrT = NJointGripperZeroTorqueControllerConfigPtr; + NJointGripperZeroTorqueController(const RobotUnitPtr&, const NJointControllerConfigPtr& config, const VirtualRobot::RobotPtr&); + + // NJointControllerInterface interface + std::string getClassName(const Ice::Current&) const override; + + // NJointController interface + + void rtRun(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration) override; + static WidgetDescription::WidgetPtr GenerateConfigDescription( + const VirtualRobot::RobotPtr&, + const std::map<std::string, ConstControlDevicePtr>&, + const std::map<std::string, ConstSensorDevicePtr>&); + + static NJointGripperZeroTorqueControllerConfigPtr GenerateConfigFromVariants(const StringVariantBaseMap& values); + + private: + std::vector<ControlTarget1DoFActuatorZeroTorque*> targets; + }; + +} // namespace armarx +