diff --git a/data/RobotAPI/VariantInfo-RobotAPI.xml b/data/RobotAPI/VariantInfo-RobotAPI.xml index af488467eceba08e1d36628858db1535ae4884fc..3e903dcb48c65673c518d3582b106d5efc5554b2 100644 --- a/data/RobotAPI/VariantInfo-RobotAPI.xml +++ b/data/RobotAPI/VariantInfo-RobotAPI.xml @@ -130,6 +130,14 @@ getterName="getRobotUnit" propertyName="RobotUnitName" propertyIsOptional="false" /> + <Proxy include="ArmarXCore/interface/observers/ObserverInterface.h" + humanName="Robot Unit Observer" + typeName="ObserverInterfacePrx" + memberName="robotUnitObserver" + getterName="getRobotUnitObserver" + propertyName="RobotUnitObserverName" + propertyIsOptional="true" + propertyDefaultValue="RobotUnitObserver" /> <Proxy include="RobotAPI/interface/components/TrajectoryPlayerInterface.h" humanName="TrajectoryPlayer Component" typeName="TrajectoryPlayerInterfacePrx" diff --git a/source/RobotAPI/components/units/HeadIKUnit.cpp b/source/RobotAPI/components/units/HeadIKUnit.cpp index 66e6477e1ce1b2cd7f25a32e4856edb21adf5dd3..4a9aa61ee61ebc005c2abd9e9c1550f010f7edbe 100644 --- a/source/RobotAPI/components/units/HeadIKUnit.cpp +++ b/source/RobotAPI/components/units/HeadIKUnit.cpp @@ -158,7 +158,7 @@ namespace armarx } - ARMARX_DEBUG << "new Head target set: " << *globalTarget; + ARMARX_DEBUG << "new Head target set: " << *globalTarget << " for " << robotNodeSetName; newTargetSet = true; } diff --git a/source/RobotAPI/components/units/RobotUnit/CMakeLists.txt b/source/RobotAPI/components/units/RobotUnit/CMakeLists.txt index 8184ff47598b96e8379eddfb239be3f3d1cc0739..6e53ccdb99a14be49b7325e9a17269447cc6a986 100644 --- a/source/RobotAPI/components/units/RobotUnit/CMakeLists.txt +++ b/source/RobotAPI/components/units/RobotUnit/CMakeLists.txt @@ -49,6 +49,7 @@ set(LIB_FILES NJointControllers/NJointTrajectoryController.cpp NJointControllers/NJointKinematicUnitPassThroughController.cpp NJointControllers/NJointHolonomicPlatformUnitVelocityPassThroughController.cpp + NJointControllers/NJointHolonomicPlatformRelativePositionController.cpp NJointControllers/NJointTCPController.cpp NJointControllers/NJointCartesianVelocityController.cpp NJointControllers/NJointCartesianTorqueController.cpp @@ -109,6 +110,7 @@ set(LIB_HEADERS NJointControllers/NJointTrajectoryController.h NJointControllers/NJointKinematicUnitPassThroughController.h NJointControllers/NJointHolonomicPlatformUnitVelocityPassThroughController.h + NJointControllers/NJointHolonomicPlatformRelativePositionController.h NJointControllers/NJointTCPController.h NJointControllers/NJointCartesianVelocityController.h NJointControllers/NJointCartesianTorqueController.h diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformRelativePositionController.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformRelativePositionController.cpp new file mode 100644 index 0000000000000000000000000000000000000000..06c0445d5d12ddcf32246fcf0c0e7f64ef88fdf8 --- /dev/null +++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformRelativePositionController.cpp @@ -0,0 +1,122 @@ +/* + * This file is part of ArmarX. + * + * Copyright (C) 2011-2017, 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/>. + * + * @package ArmarX + * @author Mirko Waechter( mirko.waechter at kit dot edu) + * @date 2017 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ +#include "NJointHolonomicPlatformRelativePositionController.h" + +namespace armarx +{ + NJointControllerRegistration<NJointHolonomicPlatformRelativePositionController> + registrationNJointHolonomicPlatformRelativePositionController("NJointHolonomicPlatformRelativePositionController"); + + + NJointHolonomicPlatformRelativePositionController::NJointHolonomicPlatformRelativePositionController( + NJointControllerDescriptionProviderInterfacePtr prov, + const NJointHolonomicPlatformRelativePositionControllerConfigPtr& cfg, + const VirtualRobot::RobotPtr&) : + pid(cfg->p, cfg->i, cfg->d, cfg->maxVelocity, cfg->maxAcceleration) + { + const SensorValueBase* sv = prov->getSensorValue(cfg->platformName); + this->sv = sv->asA<SensorValueHolonomicPlatform>(); + target = prov->getControlTarget(cfg->platformName, ControlModes::HolonomicPlatformVelocity)->asA<ControlTargetHolonomicPlatformVelocity>(); + ARMARX_CHECK_EXPRESSION_W_HINT(target, "The actuator '" << cfg->platformName << "' has no control mode " << ControlModes::HolonomicPlatformVelocity); + + pid.threadSafe = false; + + oriCtrl.maxV = cfg->maxRotationVelocity; + oriCtrl.acceleration = cfg->maxRotationAcceleration; + oriCtrl.deceleration = cfg->maxRotationAcceleration; + oriCtrl.maxDt = 0.1; + oriCtrl.p = cfg->p; + oriCtrl.positionPeriodLo = -M_PI; + oriCtrl.positionPeriodHi = M_PI; + } + + void NJointHolonomicPlatformRelativePositionController::rtRun(const IceUtil::Time&, const IceUtil::Time& timeSinceLastIteration) + { + currentPose << sv->relativePositionX, + sv->relativePositionY; + if (rtGetControlStruct().newTargetSet) + { + startPose = currentPose; + orientationOffset = sv->relativePositionRotation; + pid.reset(); + *const_cast<bool*>(&rtGetControlStruct().newTargetSet) = false; + } + + //position pid + Eigen::Vector2f relativeCurrentPose = currentPose - startPose; + pid.update(timeSinceLastIteration.toSecondsDouble(), relativeCurrentPose, rtGetControlStruct().target); + + //rotation pid + // Revert the rotation by rotating by the negative angle + Eigen::Vector2f localTargetVelocity = Eigen::Rotation2Df(-sv->relativePositionRotation) * Eigen::Vector2f(pid.getControlValue()[0], pid.getControlValue()[1]); + //ARMARX_RT_LOGF_INFO("global target vel x: %.2f y: %2.f, local target vel x: %.2f y: %2.f rotation: %2.f", pid.getControlValue()[0], pid.getControlValue()[1], localTargetVelocity[0], localTargetVelocity[1], sv->relativePositionRotation).deactivateSpam(0.1); + + target->velocityX = localTargetVelocity[0]; + target->velocityY = localTargetVelocity[1]; + // target->velocityRotation = pid.getControlValue()[2] / rad2MMFactor; + oriCtrl.dt = timeSinceLastIteration.toSecondsDouble(); + oriCtrl.accuracy = rtGetControlStruct().rotationAccuracy; + oriCtrl.currentPosition = sv->relativePositionRotation - orientationOffset; + oriCtrl.targetPosition = rtGetControlStruct().targetOrientation; + oriCtrl.currentV = sv->velocityRotation; + target->velocityRotation = oriCtrl.run(); + Eigen::Vector2f posError = pid.target.head(2) - pid.processValue.head(2); + if (posError.norm() < rtGetControlStruct().translationAccuracy) + { + target->velocityX = 0; + target->velocityY = 0; + } + float orientationError = std::abs(oriCtrl.currentPosition - oriCtrl.targetPosition); + // if (orientationError < rtGetControlStruct().rotationAccuracy) + // { + // target->velocityRotation = 0; + // } + // ARMARX_INFO << deactivateSpam(0.1) << VAROUT(oriCtrl.currentPosition) << VAROUT(orientationError); + // ARMARX_INFO << deactivateSpam(0.1) << VAROUT(target->velocityRotation) << VAROUT(sv->velocityRotation); + ARMARX_RT_LOGF_INFO("current pose x: %.2f y: %2.f, error x: %.2f y: %2.f error: %2.f ori error: %2.f", currentPose[0], currentPose[1], posError[0], posError[1], posError.norm(), orientationError).deactivateSpam(0.1); + ARMARX_RT_LOGF_INFO("new target vel: %2.f, %2.f current vel: %2.f, %2.f", target->velocityX, target->velocityY, sv->velocityX, sv->velocityY).deactivateSpam(0.1); + } + + void NJointHolonomicPlatformRelativePositionController::rtPreActivateController() + { + startPose[0] = sv->relativePositionX; + startPose[1] = sv->relativePositionY; + orientationOffset = sv->relativePositionRotation; + } + + void NJointHolonomicPlatformRelativePositionController::setTarget(float x, float y, float yaw, float translationAccuracy, float rotationAccuracy) + { + LockGuardType guard {controlDataMutex}; + getWriterControlStruct().target << x, y; + getWriterControlStruct().targetOrientation = yaw; + getWriterControlStruct().translationAccuracy = translationAccuracy; + getWriterControlStruct().rotationAccuracy = rotationAccuracy; + getWriterControlStruct().newTargetSet = true; + writeControlStruct(); + // rtUpdateControlStruct(); + } + + +} // namespace armarx + diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformRelativePositionController.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformRelativePositionController.h new file mode 100644 index 0000000000000000000000000000000000000000..a5efe0f5d5b2283f1b02bfa18be2594520849cc9 --- /dev/null +++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformRelativePositionController.h @@ -0,0 +1,108 @@ +/* + * This file is part of ArmarX. + * + * Copyright (C) 2011-2017, 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/>. + * + * @package ArmarX + * @author Mirko Waechter( mirko.waechter at kit dot edu) + * @date 2017 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ +#pragma once + + +#include <atomic> + +#include <VirtualRobot/Robot.h> + +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> + +#include "NJointController.h" +#include "../RobotUnit.h" +#include "../SensorValues/SensorValueHolonomicPlatform.h" + +#include "../ControlTargets/ControlTarget1DoFActuator.h" +#include <RobotAPI/libraries/core/PIDController.h> + +#include <RobotAPI/components/units/RobotUnit/ControlTargets/ControlTargetHolonomicPlatformVelocity.h> + +#include <RobotAPI/components/units/RobotUnit/BasicControllers.h> +namespace armarx +{ + + TYPEDEF_PTRS_HANDLE(NJointHolonomicPlatformRelativePositionControllerConfig); + class NJointHolonomicPlatformRelativePositionControllerConfig : virtual public NJointControllerConfig + { + public: + std::string platformName; + float p = 0.5f; + float i = 0.0f; + float d = 0.0f; + float maxVelocity = 300; + float maxAcceleration = 100; + float maxRotationVelocity = 0.2; + float maxRotationAcceleration = 0.1; + // float rad2MMFactor = 50.0f; + }; + + struct NJointHolonomicPlatformRelativePositionControllerTarget + { + Eigen::Vector2f target; // x,y + float targetOrientation; + float translationAccuracy = 0.0f; + float rotationAccuracy = 0.0f; + bool newTargetSet = false; + }; + + TYPEDEF_PTRS_HANDLE(NJointHolonomicPlatformRelativePositionController); + class NJointHolonomicPlatformRelativePositionController: + virtual public NJointControllerWithTripleBuffer<NJointHolonomicPlatformRelativePositionControllerTarget> + { + public: + using ConfigPtrT = NJointHolonomicPlatformRelativePositionControllerConfigPtr; + + inline NJointHolonomicPlatformRelativePositionController( + NJointControllerDescriptionProviderInterfacePtr prov, + const NJointHolonomicPlatformRelativePositionControllerConfigPtr& cfg, + const VirtualRobot::RobotPtr&); + + inline virtual void rtRun(const IceUtil::Time&, const IceUtil::Time& timeSinceLastIteration) override; + inline virtual void rtPreActivateController() override; + + //ice interface + inline virtual std::string getClassName(const Ice::Current& = GlobalIceCurrent) const override + { + return "NJointHolonomicPlatformRelativePositionController"; + } + + void setTarget(float x, float y, float yaw, float translationAccuracy, float rotationAccuracy); + + + protected: + const SensorValueHolonomicPlatform* sv; + MultiDimPIDController pid; + PositionThroughVelocityControllerWithAccelerationBoundsAndPeriodicPosition oriCtrl; + ControlTargetHolonomicPlatformVelocity* target; + Eigen::Vector2f startPose, currentPose; + float orientationOffset; + // float rad2MMFactor; + + virtual void onInitComponent() override {} + virtual void onConnectComponent() override {} + }; +} // namespace armarx + + diff --git a/source/RobotAPI/components/units/RobotUnit/RobotUnit.cpp b/source/RobotAPI/components/units/RobotUnit/RobotUnit.cpp index 7eff0cb03a82764463523f7ddc66245386d2ce92..5679160c7e1e8035e2bc0804ae5c86a95d008a5e 100644 --- a/source/RobotAPI/components/units/RobotUnit/RobotUnit.cpp +++ b/source/RobotAPI/components/units/RobotUnit/RobotUnit.cpp @@ -563,6 +563,19 @@ namespace armarx ); ARMARX_CHECK_EXPRESSION(ctrl); unit->pt = ctrl; + + NJointHolonomicPlatformRelativePositionControllerConfigPtr configRelativePositionCtrlCfg = new NJointHolonomicPlatformRelativePositionControllerConfig; + configRelativePositionCtrlCfg->platformName = robotPlatformName; + auto ctrlRelativePosition = NJointHolonomicPlatformRelativePositionControllerPtr::dynamicCast( + createNJointController( + "NJointHolonomicPlatformRelativePositionController", configName + "_RelativePositionContoller", + configRelativePositionCtrlCfg, false, true + ) + ); + ARMARX_CHECK_EXPRESSION(ctrlRelativePosition); + unit->pt = ctrl; + unit->relativePosCtrl = ctrlRelativePosition; + unit->platformSensorIndex = sensorDevices.index(robotPlatformName); //add addUnit(std::move(unit)); diff --git a/source/RobotAPI/components/units/RobotUnit/Units/PlatformSubUnit.cpp b/source/RobotAPI/components/units/RobotUnit/Units/PlatformSubUnit.cpp index 18b50b0cda5ee8abd405e2aad3efe55f47c4ff5a..ac4f64be14afb2f0cde6117575622e90a7e3a1b2 100644 --- a/source/RobotAPI/components/units/RobotUnit/Units/PlatformSubUnit.cpp +++ b/source/RobotAPI/components/units/RobotUnit/Units/PlatformSubUnit.cpp @@ -90,7 +90,15 @@ void armarx::PlatformSubUnit::moveTo(Ice::Float rx, Ice::Float ry, Ice::Float rr void armarx::PlatformSubUnit::moveRelative(Ice::Float rx, Ice::Float ry, Ice::Float rr, Ice::Float lac, Ice::Float rac, const Ice::Current&) { - ARMARX_WARNING << "NYI"; + if (!relativePosCtrl->isControllerActive()) + { + relativePosCtrl->activateController(); + } + //holding the mutex here could deadlock + // std::lock_guard<std::mutex> guard {dataMutex}; + ARMARX_INFO << "target orientation: " << rr; + relativePosCtrl->setTarget(rx, ry, rr, lac, rac); + } void armarx::PlatformSubUnit::setMaxVelocities(Ice::Float mxVLin, Ice::Float mxVAng, const Ice::Current&) diff --git a/source/RobotAPI/components/units/RobotUnit/Units/PlatformSubUnit.h b/source/RobotAPI/components/units/RobotUnit/Units/PlatformSubUnit.h index 1b75e30f38acdf2ffd7b67b3ebe3bb32454ba6d4..a9df471978bcd44b1f776c498b421ae35a862204 100644 --- a/source/RobotAPI/components/units/RobotUnit/Units/PlatformSubUnit.h +++ b/source/RobotAPI/components/units/RobotUnit/Units/PlatformSubUnit.h @@ -31,6 +31,7 @@ #include <VirtualRobot/MathTools.h> #include <RobotAPI/components/units/PlatformUnit.h> +#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformRelativePositionController.h> #include <RobotAPI/libraries/core/Pose.h> #include "RobotUnitSubUnit.h" @@ -64,6 +65,7 @@ namespace armarx void stopPlatform(const Ice::Current& c = GlobalIceCurrent) override; NJointHolonomicPlatformUnitVelocityPassThroughControllerPtr pt; + NJointHolonomicPlatformRelativePositionControllerPtr relativePosCtrl; std::size_t platformSensorIndex; protected: Eigen::Matrix4f getRelativePose() const; diff --git a/source/RobotAPI/components/units/RobotUnit/util/RtTiming.h b/source/RobotAPI/components/units/RobotUnit/util/RtTiming.h index 65cf13a5717de73e70769603d6188011a8ceaa57..a9feb50c732672846a87813a87c9a309bc3c1aad 100644 --- a/source/RobotAPI/components/units/RobotUnit/util/RtTiming.h +++ b/source/RobotAPI/components/units/RobotUnit/util/RtTiming.h @@ -31,9 +31,10 @@ namespace armarx { inline IceUtil::Time rtNow() { - using namespace std::chrono; - auto epoch = time_point_cast<microseconds>(high_resolution_clock::now()).time_since_epoch(); - return IceUtil::Time::microSeconds(duration_cast<milliseconds>(epoch).count()); + return IceUtil::Time::now(IceUtil::Time::Monotonic); + // using namespace std::chrono; + // auto epoch = time_point_cast<microseconds>(high_resolution_clock::now()).time_since_epoch(); + // return IceUtil::Time::microSeconds(duration_cast<milliseconds>(epoch).count()); } } diff --git a/source/RobotAPI/libraries/RobotAPINJointControllers/CMakeLists.txt b/source/RobotAPI/libraries/RobotAPINJointControllers/CMakeLists.txt index a4c087f9e1a62f430fa12cae5e5a0c6c7abc8bfe..73fa0080373f5152050fd873f7aa337f8851aab2 100644 --- a/source/RobotAPI/libraries/RobotAPINJointControllers/CMakeLists.txt +++ b/source/RobotAPI/libraries/RobotAPINJointControllers/CMakeLists.txt @@ -7,7 +7,7 @@ find_package(Eigen3 QUIET) find_package(Simox ${ArmarX_Simox_VERSION} QUIET) find_package(DMP QUIET) find_package(MMMCore QUIET) -find_package(MMMToolsQUIET) +find_package(MMMTools QUIET) armarx_build_if(Eigen3_FOUND "Eigen3 not available") armarx_build_if(Simox_FOUND "Simox-VirtualRobot not available")