diff --git a/source/RobotAPI/components/units/RobotUnit/CMakeLists.txt b/source/RobotAPI/components/units/RobotUnit/CMakeLists.txt index dbaaf4873bd64b8aede4752f0b8cdc8de3029579..626d2fb4c770f6ac632fd36618d28be861c9f28c 100755 --- a/source/RobotAPI/components/units/RobotUnit/CMakeLists.txt +++ b/source/RobotAPI/components/units/RobotUnit/CMakeLists.txt @@ -53,6 +53,7 @@ set(LIB_FILES NJointControllers/NJointCartesianVelocityControllerWithRamp.cpp NJointControllers/NJointCartesianWaypointController.cpp NJointControllers/NJointCartesianNaturalPositionController.cpp + NJointControllers/NJointKneeHipController.cpp ControllerParts/CartesianImpedanceController.cpp @@ -131,6 +132,7 @@ set(LIB_HEADERS NJointControllers/NJointCartesianVelocityControllerWithRamp.h NJointControllers/NJointCartesianWaypointController.h NJointControllers/NJointCartesianNaturalPositionController.h + NJointControllers/NJointKneeHipController.h ControllerParts/CartesianImpedanceController.h diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointKneeHipController.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointKneeHipController.cpp new file mode 100644 index 0000000000000000000000000000000000000000..faefcca81ae8160e2db3f94761ed4f22b40fd1e0 --- /dev/null +++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointKneeHipController.cpp @@ -0,0 +1,145 @@ +#include "NJointKneeHipController.h" + +#include <SimoxUtility/math/distance/angle_between.h> + +#include <ArmarXCore/core/logging/Logging.h> +#include <ArmarXCore/interface/observers/VariantBase.h> + +// #include <armar7/rt/units/njoint_controller/common/controller_types.h> +// #include <armar7/rt/units/njoint_controller/knee_hip_controller/aron/ControllerConfig.aron.generated.h> +// #include <armar7/rt/units/njoint_controller/knee_hip_controller/aron_conversions.h> + + + + +namespace armarx + +{ + const armarx::NJointControllerRegistration<NJointKneeHipController> + registrationControllerNJointKneeHipController( + "NJointKneeHipController"); + + NJointKneeHipController::NJointKneeHipController(RobotUnit* robotUnit, + const armarx::NJointControllerConfigPtr& config, + const VirtualRobot::RobotPtr&) + { + ARMARX_RT_LOGF("Creating knee hip controller"); + + ARMARX_CHECK_EXPRESSION(robotUnit); + + // config + ConfigPtrT cfg = ConfigPtrT::dynamicCast(config); + ARMARX_CHECK_EXPRESSION(cfg); + + // const arondto::Config configData = arondto::Config::FromAron(cfg->config); + + // robot + ARMARX_RT_LOGF("Setting up nodes"); + { + _rtRobot = useSynchronizedRtRobot(); + _rtRobot->setThreadsafe(false); + ARMARX_CHECK_NOT_NULL(_rtRobot); + + // _rtKneeNode = _rtRobot->getRobotNode(configData.params.kneeJointName); + // _rtHipNode = _rtRobot->getRobotNode(configData.params.hipJointName); + // _rtHipBodyNode = _rtRobot->getRobotNode(configData.params.hipBodyName); + const auto *kneeJointName = "Knee"; + const auto *hipJointName = "Hip"; + const auto *hipBodyName = "Hip_body"; + + + _rtKneeNode = _rtRobot->getRobotNode(kneeJointName); + _rtHipNode = _rtRobot->getRobotNode(hipJointName); + _rtHipBodyNode = _rtRobot->getRobotNode(hipBodyName); + ARMARX_CHECK_NOT_NULL(_rtKneeNode); + ARMARX_CHECK_NOT_NULL(_rtHipNode); + ARMARX_CHECK_NOT_NULL(_rtHipBodyNode); + + _rtKneeCtrlTarget = useControlTarget<armarx::ControlTarget1DoFActuatorPosition>( + kneeJointName, armarx::ControlModes::Position1DoF); + ARMARX_CHECK_NOT_NULL(_rtKneeCtrlTarget); + _rtHipCtrlTarget = useControlTarget<armarx::ControlTarget1DoFActuatorPosition>( + hipJointName, armarx::ControlModes::Position1DoF); + ARMARX_CHECK_NOT_NULL(_rtHipCtrlTarget); + } + + ARMARX_RT_LOGF("Nodes set up successfully"); + } + + NJointKneeHipController::~NJointKneeHipController() = default; + + // void + // KneeHipController::updateConfig(const ::armarx::aron::data::dto::DictPtr& dto, + // const Ice::Current& /*iceCurrent*/) + // { + // // const auto updateConfigDto = arondto::Config::FromAron(dto); + + // // Config config; + // // fromAron(updateConfigDto, config); + + // // setControlStruct(config); + // } + + void + NJointKneeHipController::onInitNJointController() + { + } + + void + NJointKneeHipController::onConnectNJointController() + { + } + + std::string + NJointKneeHipController::getClassName(const Ice::Current&) const + { + return "KneeHipController"; + } + + void + NJointKneeHipController::rtRun(const IceUtil::Time& /*sensorValuesTimestamp*/, + const IceUtil::Time& /*timeSinceLastIteration*/) + { + const float currentHipJointValue = _rtHipNode->getJointValue(); + const auto hipRotation = + _rtHipBodyNode->getOrientationInRootFrame() * Eigen::Vector3f::UnitY(); + + // angle between robot root and hip body in the yz-plane + // leaning forwards < 90° = upright < leaning backwards + const float hipAngle = simox::math::angle_between_vec3f_vec3f( + Eigen::Vector3f::UnitY(), hipRotation, Eigen::Vector3f::UnitX()); + + // hip joint has positive angles leaning forwards (inverse to hipAngle) + float targetHipAngle = + currentHipJointValue + hipAngle - M_PI_2 + rtGetControlStruct().bowAngle; + + float targetKneeAngle = rtGetControlStruct().kneeAngle; + + // check reachability + const bool targetReachable = _rtKneeNode->checkJointLimits(targetKneeAngle) && + _rtHipNode->checkJointLimits(targetHipAngle); + if (not targetReachable) + { + // limit joint ranges to avoid damage + targetKneeAngle = std::clamp( + targetKneeAngle, _rtKneeNode->getJointLimitLow(), _rtKneeNode->getJointLimitHigh()); + targetHipAngle = std::clamp( + targetHipAngle, _rtHipNode->getJointLimitLow(), _rtHipNode->getJointLimitHigh()); + } + + _rtKneeCtrlTarget->position = targetKneeAngle; + _rtHipCtrlTarget->position = targetHipAngle; + } + + void + NJointKneeHipController::rtPreActivateController() + { + } + + void + NJointKneeHipController::rtPostDeactivateController() + { + } + + +} // namespace armarx diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointKneeHipController.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointKneeHipController.h new file mode 100644 index 0000000000000000000000000000000000000000..94fc676f84312ae446ee16a8a040c05d9a734e24 --- /dev/null +++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointKneeHipController.h @@ -0,0 +1,101 @@ +/* + * 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 armar7_rt + * @author Tobias Gröger ( tobias dot groeger at student dot kit dot edu ) + * @date 2023 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ +#pragma once + +#include <RobotAPI/components/units/RobotUnit/ControlTargets/ControlTarget1DoFActuator.h> +#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointController.h> +#include <RobotAPI/components/units/RobotUnit/RobotUnit.h> + +namespace armarx +{ + struct Params + { + std::string kneeJointName; + std::string hipJointName; + std::string hipBodyName; + }; + + struct Config + { + Params params; + float kneeAngle; + float bowAngle; + }; + + TYPEDEF_PTRS_HANDLE(NJointKneeHipControllerConfig); + + class NJointKneeHipControllerConfig : virtual public armarx::NJointControllerConfig + { + public: + std::string deviceName1; + std::string deviceName; + std::string controlMode; + }; + + TYPEDEF_PTRS_HANDLE(NJointKneeHipController); + + class NJointKneeHipController : + virtual public armarx::NJointControllerWithTripleBuffer<Config> + { + public: + using ConfigPtrT = NJointKneeHipControllerConfigPtr; + + NJointKneeHipController(RobotUnit* robotUnit, + const armarx::NJointControllerConfigPtr& config, + const VirtualRobot::RobotPtr& /* unused */); + + ~NJointKneeHipController() override; + + // void updateConfig(const ::armarx::aron::data::dto::DictPtr& dto, + // const Ice::Current& iceCurrent = Ice::emptyCurrent) ; + + protected: + // + // NJointControllerInterface interface + // + + void onInitNJointController() override; + + void onConnectNJointController() override; + + std::string getClassName(const Ice::Current& = Ice::emptyCurrent) const override; + + void rtRun(const IceUtil::Time& sensorValuesTimestamp, + const IceUtil::Time& timeSinceLastIteration) override; + + void rtPreActivateController() override; + void rtPostDeactivateController() override; + + // ---------------- + + private: + // rt variables + VirtualRobot::RobotPtr _rtRobot; + VirtualRobot::RobotNodePtr _rtKneeNode; + VirtualRobot::RobotNodePtr _rtHipNode; + VirtualRobot::RobotNodePtr _rtHipBodyNode; + + armarx::ControlTarget1DoFActuatorPosition* _rtKneeCtrlTarget; + armarx::ControlTarget1DoFActuatorPosition* _rtHipCtrlTarget; + }; + +} // namespace armarx diff --git a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleUnits.cpp b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleUnits.cpp index 5304a0aa8a0e6716b6c9c8266c01d9db61e9ee6a..49b6d3002006fa8b6675e3b4748e4bd31b50e53a 100644 --- a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleUnits.cpp +++ b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleUnits.cpp @@ -25,6 +25,7 @@ #include <ArmarXCore/core/IceGridAdmin.h> #include <ArmarXCore/core/IceManager.h> +#include "RobotAPI/components/units/RobotUnit/NJointControllers/NJointKneeHipController.h" #include "RobotAPI/components/units/RobotUnit/SensorValues/SensorValueHolonomicPlatform.h" #include "RobotAPI/components/units/RobotUnit/Units/LocalizationSubUnit.h" #include <RobotAPI/components/units/RobotUnit/Devices/GlobalRobotPoseSensorDevice.h> @@ -277,6 +278,7 @@ namespace armarx::RobotUnitModule auto controlMode = requestedControlMode; using CtargT = std::remove_const_t<std::remove_reference_t<decltype(*tpptr)>>; NJointKinematicUnitPassThroughControllerPtr& pt = ctrl; + auto testMode = [&](const auto& m) { @@ -325,17 +327,37 @@ namespace armarx::RobotUnitModule std::replace(ctrl_name.begin(), ctrl_name.end(), '.', '_'); std::replace(ctrl_name.begin(), ctrl_name.end(), '-', '_'); std::replace(ctrl_name.begin(), ctrl_name.end(), ':', '_'); - const NJointControllerBasePtr& nJointCtrl = + const NJointControllerBasePtr& nJointCtrl1 = _module<ControllerManagement>().createNJointController( "NJointKinematicUnitPassThroughController", ctrl_name, config, false, true); - pt = NJointKinematicUnitPassThroughControllerPtr::dynamicCast(nJointCtrl); + pt = NJointKinematicUnitPassThroughControllerPtr::dynamicCast(nJointCtrl1); ARMARX_CHECK_EXPRESSION(pt); } + + + }; + + if (controlDevice->getDeviceName() == "Knee") + { + NJointKneeHipControllerConfigPtr config = new NJointKneeHipControllerConfig; + config->controlMode = positionControlMode; + config->deviceName = controlDeviceName; + auto ctrl_name = "KneeHipController"; + + const NJointControllerBasePtr& nJointCtrl2 = + _module<ControllerManagement>().createNJointController( + "NJointKneeHipController", ctrl_name, config, false, true); + NJointKneeHipControllerPtr kh = + NJointKneeHipControllerPtr::dynamicCast(nJointCtrl2); + ARMARX_CHECK_EXPRESSION(kh); + } + + init_controller( positionControlMode, ad.ctrlPos, (ControlTarget1DoFActuatorPosition*)0); init_controller(