diff --git a/.gitignore b/.gitignore index efe7e6e621bb44ff3b61c296ce841445f5353451..6bbc3ffa11b5ac3f4e9acca1b3eeeb70d886e60d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1,23 @@ -.keep_in_git +/build/* +!/build/.gitkeep +!.gitkeep +!.gitignore -/build* - -source/RobotAPI/Test.h +source/*/Test.h *.bak *# .#* *~ +*.swp +.*.kate-swp +.*.swo +*.pyc .DS_Store CMakeFiles CMakeCache.txt +CMakeLists.txt.user *.o *.os @@ -22,3 +28,18 @@ CMakeCache.txt *.dylib moc_* +# eclipse stuff +.project +.pydevproject +.settings +.metadata +.cproject +.project + +# MemoryX +.cache +mongod.log* +data/db/ +data/dbdump/ + + diff --git a/CMakeLists.txt b/CMakeLists.txt index 19d6498c21e86f3eb2beeaff748c61a582a631fc..f178c8c26ec65b626e0b407d4327c125fb54a153 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ include(${ArmarXCore_CMAKE_DIR}/ArmarXProject.cmake) armarx_project("RobotAPI") add_subdirectory(source) +add_subdirectory(interface) install_project() diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..59c35598d7a14e225c75952ce619863348a8b74a --- /dev/null +++ b/interface/CMakeLists.txt @@ -0,0 +1,7 @@ +### +### CMakeLists.txt file for ArmarX Interfaces +### + +set(ROBOTAPI_INTERFACE_DEPEND ArmarXCore) +# generate the interface library +armarx_interfaces_generate_library(RobotAPI 0.1.0 0 ${ROBOTAPI_INTERFACE_DEPEND}) diff --git a/interface/slice/units/ForceTorqueUnit.ice b/interface/slice/units/ForceTorqueUnit.ice new file mode 100644 index 0000000000000000000000000000000000000000..93fb1be4a0630b35ea49cab956775d4040974aa7 --- /dev/null +++ b/interface/slice/units/ForceTorqueUnit.ice @@ -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 Lesser General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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 Lesser 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 + * @author Mirko Waechter <waechter at kit dot edu> + * @copyright 2013 Mirko Waechter + * @license http://www.gnu.org/licenses/gpl.txt + * GNU General Public License + */ + +#ifndef _ARMARX_ROBOTAPI_UNITS_FORCETORQUE_SLICE_ +#define _ARMARX_ROBOTAPI_UNITS_FORCETORQUE_SLICE_ + +#include <units/UnitInterface.ice> +#include <core/UserException.ice> +#include <core/BasicTypes.ice> +#include <observers/VariantBase.ice> +#include <observers/ObserverInterface.ice> +#include <robotstate/RobotState.ice> + +module armarx +{ + + + sequence<string> StringMap; + interface ForceTorqueUnitInterface extends armarx::SensorActorUnitInterface + { + void setOffset(FramedVector3Map forceTorqueOffsets); + void setToNull(StringMap sensorNames); + }; + + + + interface ForceTorqueUnitListener + { + void reportSensorValues(string type, FramedVector3Map forces); + }; + + interface ForceTorqueUnitObserverInterface extends ObserverInterface, ForceTorqueUnitListener + { + + }; + +}; + +#endif diff --git a/interface/slice/units/TCPControlUnit.ice b/interface/slice/units/TCPControlUnit.ice new file mode 100644 index 0000000000000000000000000000000000000000..6b7517f5f42fbe41cb08266ce4b053d859a38438 --- /dev/null +++ b/interface/slice/units/TCPControlUnit.ice @@ -0,0 +1,63 @@ +/* + * This file is part of ArmarX. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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 Lesser 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 + * @author Mirko Waechter <waechter at kit dot edu> + * @copyright 2013 Mirko Waechter + * @license http://www.gnu.org/licenses/gpl.txt + * GNU General Public License + */ + +#ifndef _ARMARX_ROBOTAPI_UNITS_FORCETORQUE_SLICE_ +#define _ARMARX_ROBOTAPI_UNITS_FORCETORQUE_SLICE_ + +#include <units/UnitInterface.ice> +#include <core/UserException.ice> +#include <core/BasicTypes.ice> +#include <observers/VariantBase.ice> +#include <observers/ObserverInterface.ice> +#include <robotstate/RobotState.ice> +#include <robotstate/PoseBase.ice> + +module armarx +{ + + interface TCPControlUnitInterface extends armarx::SensorActorUnitInterface + { + void setCycleTime(int milliseconds); +// void setTCPVelocity(string robotNodeSetName, FramedVector3Base translationVelocity, FramedVector3Base orientationVelocityRPY); + void setTCPVelocity(string robotNodeSetName, string tcpNodeName, FramedVector3Base translationVelocity, FramedVector3Base orientationVelocityRPY); + + }; + + + dictionary<string, FramedPoseBase> FramedPoseBaseMap; + interface TCPControlUnitListener + { + void reportTCPPose(FramedPoseBaseMap tcpPoses); + void reportTCPVelocities(FramedVector3Map tcpTranslationVelocities, FramedVector3Map tcpOrienationVelocities); + + }; + + interface TCPControlUnitObserverInterface extends ObserverInterface, TCPControlUnitListener + { + + }; + + +}; + +#endif diff --git a/source/RobotAPI/CMakeLists.txt b/source/RobotAPI/CMakeLists.txt index 1000114d8d592e8078c0f1ad2b18b0e79a175ab9..475cc9398af64bbc32318c7edb7a311f92ae2e9c 100644 --- a/source/RobotAPI/CMakeLists.txt +++ b/source/RobotAPI/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(core) add_subdirectory(motioncontrol) add_subdirectory(applications) +add_subdirectory(units) diff --git a/source/RobotAPI/applications/CMakeLists.txt b/source/RobotAPI/applications/CMakeLists.txt index 6135bbd62b00d9c085039eb23e53326e051c3334..578f1ace321c1843e987fc1151db6e1362cf3c7e 100644 --- a/source/RobotAPI/applications/CMakeLists.txt +++ b/source/RobotAPI/applications/CMakeLists.txt @@ -1,4 +1,5 @@ - +add_subdirectory(ForceTorqueObserver) add_subdirectory(MotionControlTest) +add_subdirectory(TCPControlUnit) diff --git a/source/RobotAPI/applications/ForceTorqueObserver/CMakeLists.txt b/source/RobotAPI/applications/ForceTorqueObserver/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..3a02531313f90edf32ded55e11ec325969453925 --- /dev/null +++ b/source/RobotAPI/applications/ForceTorqueObserver/CMakeLists.txt @@ -0,0 +1,28 @@ + +armarx_component_set_name(ForceTorqueObserver) + +set(COMPONENT_BUILD TRUE) + +find_package(Simox QUIET) +armarx_build_if(Simox_FOUND "Simox-VirtualRobot not available") + +armarx_build_if(COMPONENT_BUILD "component disabled") + +# check if ArmarXCoreUnits library gets built +# LOCATION is NOT-FOUND (equal to FALSE) if library is disabled +GET_TARGET_PROPERTY(ArmarXCoreUnits_ENABLED ArmarXCoreUnits LOCATION) +armarx_build_if(ArmarXCoreUnits_ENABLED "ArmarXCoreUnits library disabled") + +GET_TARGET_PROPERTY(ArmarXCoreObservers_ENABLED ArmarXCoreObservers LOCATION) +armarx_build_if(ArmarXCoreObservers_ENABLED "ArmarXCoreObservers library disabled") + + +if (ARMARX_BUILD) + set(COMPONENT_LIBS RobotAPIUnits RobotAPICore RobotAPIInterfaces ArmarXInterfaces ArmarXCore ArmarXCoreObservers ArmarXCoreRemoteRobot) + + set(SOURCES "") + set(HEADERS ForceTorqueObserverApp.h) + + armarx_component_add_executable("${SOURCES}" "${HEADERS}") + +endif() diff --git a/source/RobotAPI/applications/ForceTorqueObserver/ForceTorqueObserverApp.h b/source/RobotAPI/applications/ForceTorqueObserver/ForceTorqueObserverApp.h new file mode 100755 index 0000000000000000000000000000000000000000..cab40777f7e5607e02dd0df0e5974c4f44d8af5f --- /dev/null +++ b/source/RobotAPI/applications/ForceTorqueObserver/ForceTorqueObserverApp.h @@ -0,0 +1,41 @@ +/** + * This file is part of ArmarX. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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 Lesser 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 ArmarXCore::applications + * @author Kai Welke (weöle dot at kit dot edu) + * @date 2012 + * @copyright http://www.gnu.org/licenses/gpl.txt + * GNU General Public License + */ + + +#include <Core/core/application/Application.h> +#include <RobotAPI/units/ForceTorqueObserver.h> + +namespace armarx +{ + class ForceTorqueObserverApp : + virtual public armarx::Application + { + void setup(const ManagedIceObjectRegistryInterfacePtr& registry, Ice::PropertiesPtr properties) + { + registry->addObject( Component::create<ForceTorqueObserver>(properties) ); + } + }; +} + + + diff --git a/source/RobotAPI/applications/MotionControl/CMakeLists.txt b/source/RobotAPI/applications/MotionControl/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..ea23a4dc5095874712bbc14592dadc8104cb239f --- /dev/null +++ b/source/RobotAPI/applications/MotionControl/CMakeLists.txt @@ -0,0 +1,28 @@ + +armarx_component_set_name(MotionControl) + +set(COMPONENT_BUILD TRUE) + +find_package(Simox QUIET) +armarx_build_if(Simox_FOUND "Simox-VirtualRobot not available") + +armarx_build_if(COMPONENT_BUILD "component disabled") + +# check if ArmarXCoreUnits library gets built +# LOCATION is NOT-FOUND (equal to FALSE) if library is disabled +GET_TARGET_PROPERTY(ArmarXCoreUnits_ENABLED ArmarXCoreUnits LOCATION) +armarx_build_if(ArmarXCoreUnits_ENABLED "ArmarXCoreUnits library disabled") + +GET_TARGET_PROPERTY(ArmarXCoreObservers_ENABLED ArmarXCoreObservers LOCATION) +armarx_build_if(ArmarXCoreObservers_ENABLED "ArmarXCoreObservers library disabled") + + +if (ARMARX_BUILD) + set(COMPONENT_LIBS MotionControl RobotAPICore ArmarXInterfaces ArmarXCore ArmarXCoreObservers ArmarXCoreRobotStateComponent ArmarXCoreStatechart ArmarXCoreOperations) + + set(SOURCES "") + set(HEADERS MotionControlApp.h) + + armarx_component_add_executable("${SOURCES}" "${HEADERS}") + +endif() diff --git a/source/RobotAPI/applications/MotionControl/MotionControlApp.h b/source/RobotAPI/applications/MotionControl/MotionControlApp.h new file mode 100755 index 0000000000000000000000000000000000000000..62045985b2efc3df6a18e8216bfa0e2a2139d9eb --- /dev/null +++ b/source/RobotAPI/applications/MotionControl/MotionControlApp.h @@ -0,0 +1,41 @@ +/** + * This file is part of ArmarX. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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 Lesser 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 ArmarXCore::applications + * @author Kai Welke (weöle dot at kit dot edu) + * @date 2012 + * @copyright http://www.gnu.org/licenses/gpl.txt + * GNU General Public License + */ + + +#include <Core/core/application/Application.h> +#include <RobotAPI/motioncontrol/MotionControl.h> + +namespace armarx +{ + class MotionControlApp : + virtual public armarx::Application + { + void setup(const ManagedIceObjectRegistryInterfacePtr& registry, Ice::PropertiesPtr properties) + { + registry->addObject( Component::create<MotionControl::MotionControlOfferer>(properties) ); + } + }; +} + + + diff --git a/source/RobotAPI/applications/MotionControlTest/MotionControlTestApp.h b/source/RobotAPI/applications/MotionControlTest/MotionControlTestApp.h index abac52768b1f277e1da164066332e9f3119d5cbc..b6f7a128c0e1f5b6e423905c2cbd55dad7b46756 100644 --- a/source/RobotAPI/applications/MotionControlTest/MotionControlTestApp.h +++ b/source/RobotAPI/applications/MotionControlTest/MotionControlTestApp.h @@ -32,7 +32,7 @@ namespace armarx { void setup(const ManagedIceObjectRegistryInterfacePtr& registry, Ice::PropertiesPtr properties) { - registry->addObject( Component::create<MotionControl::MotionControlHandler>(properties) ); + registry->addObject( Component::create<MotionControl::MotionControlOfferer>(properties) ); } }; } diff --git a/source/RobotAPI/applications/TCPControlUnit/CMakeLists.txt b/source/RobotAPI/applications/TCPControlUnit/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..c3b5fe509d9bce689deaef57f3a5d15400687d31 --- /dev/null +++ b/source/RobotAPI/applications/TCPControlUnit/CMakeLists.txt @@ -0,0 +1,28 @@ + +armarx_component_set_name(TCPControlUnit) + +set(COMPONENT_BUILD TRUE) + +find_package(Simox QUIET) +armarx_build_if(Simox_FOUND "Simox-VirtualRobot not available") + +armarx_build_if(COMPONENT_BUILD "component disabled") + +# check if ArmarXCoreUnits library gets built +# LOCATION is NOT-FOUND (equal to FALSE) if library is disabled +GET_TARGET_PROPERTY(ArmarXCoreUnits_ENABLED ArmarXCoreUnits LOCATION) +armarx_build_if(ArmarXCoreUnits_ENABLED "ArmarXCoreUnits library disabled") + +GET_TARGET_PROPERTY(ArmarXCoreObservers_ENABLED ArmarXCoreObservers LOCATION) +armarx_build_if(ArmarXCoreObservers_ENABLED "ArmarXCoreObservers library disabled") + + +if (ARMARX_BUILD) + set(COMPONENT_LIBS RobotAPIUnits RobotAPICore RobotAPIInterfaces ArmarXInterfaces ArmarXCore ArmarXCoreObservers ArmarXCoreRemoteRobot) + + set(SOURCES "") + set(HEADERS TCPControlUnitApp.h) + + armarx_component_add_executable("${SOURCES}" "${HEADERS}") + +endif() diff --git a/source/RobotAPI/applications/TCPControlUnit/TCPControlUnitApp.h b/source/RobotAPI/applications/TCPControlUnit/TCPControlUnitApp.h new file mode 100755 index 0000000000000000000000000000000000000000..4ab7d2dee5cd1843c729a4ea0f3ab2571b6cf801 --- /dev/null +++ b/source/RobotAPI/applications/TCPControlUnit/TCPControlUnitApp.h @@ -0,0 +1,43 @@ +/** + * This file is part of ArmarX. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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 Lesser 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 ArmarXCore::applications + * @author Kai Welke (weöle dot at kit dot edu) + * @date 2012 + * @copyright http://www.gnu.org/licenses/gpl.txt + * GNU General Public License + */ + + +#include <Core/core/application/Application.h> +#include <RobotAPI/units/TCPControlUnit.h> +#include <RobotAPI/units/TCPControlUnitObserver.h> + +namespace armarx +{ + class TCPControlUnitApp : + virtual public armarx::Application + { + void setup(const ManagedIceObjectRegistryInterfacePtr& registry, Ice::PropertiesPtr properties) + { + registry->addObject( Component::create<TCPControlUnit>(properties) ); + registry->addObject( Component::create<TCPControlUnitObserver>(properties) ); + } + }; +} + + + diff --git a/source/RobotAPI/core/CMakeLists.txt b/source/RobotAPI/core/CMakeLists.txt index 1761fc4df670e2dd3536f51daaa96a23e187925f..73413bd6fe23dab50c7542ca7763c872ae2b53f4 100644 --- a/source/RobotAPI/core/CMakeLists.txt +++ b/source/RobotAPI/core/CMakeLists.txt @@ -15,10 +15,13 @@ if (ARMARX_BUILD) set(LIB_VERSION 0.1.0) set(LIB_SOVERSION 0) - set(LIBS ArmarXInterfaces ArmarXCore ArmarXCoreObservers ArmarXCoreStatechart ArmarXCoreRobotStateComponent) + set(LIBS ArmarXInterfaces ArmarXCore ArmarXCoreObservers ArmarXCoreStatechart ArmarXCoreRobotStateComponent ${VirtualRobot_LIBRARIES}) + + set(LIB_FILES RobotStatechartContext.cpp + ) + set(LIB_HEADERS RobotStatechartContext.h + ) - set(LIB_FILES RobotStatechartContext.cpp) - set(LIB_HEADERS RobotStatechartContext.h) add_library(${LIB_NAME} SHARED ${LIB_FILES} ${LIB_HEADERS}) diff --git a/source/RobotAPI/core/RobotStatechartContext.cpp b/source/RobotAPI/core/RobotStatechartContext.cpp index 98a186ff330cafb814ea1effd732d654262182e4..5b85b23d6dcd2f4c5e6c0e0fc1ae59c408d28f18 100644 --- a/source/RobotAPI/core/RobotStatechartContext.cpp +++ b/source/RobotAPI/core/RobotStatechartContext.cpp @@ -26,7 +26,6 @@ #include <Core/statechart/Statechart.h> #include <Core/robotstate/remote/RemoteRobot.h> #include <Core/robotstate/remote/ArmarPose.h> -#include <Core/robotstate/RobotStateObjectFactories.h> //#include <VirtualRobot/VirtualRobot.h> @@ -43,10 +42,9 @@ namespace armarx // StatechartContext::onInitStatechart(); ARMARX_LOG << eINFO << "Init RobotStatechartContext" << flush; - RobotStateObjectFactories::addFactories(getIceManager()->getCommunicator()); kinematicUnitObserverName = getProperty<std::string>("KinematicUnitObserverName").getValue(); - + usingProxy(getProperty<std::string>("KinematicUnitName").getValue()); usingProxy("RobotStateComponent"); usingProxy(kinematicUnitObserverName); } diff --git a/source/RobotAPI/core/RobotStatechartContext.h b/source/RobotAPI/core/RobotStatechartContext.h index 7a3e92b49e139fd80e97045377557bfe2cd39d9b..1992440daa299f9766d9d6aec9cab0efd2ab8452 100644 --- a/source/RobotAPI/core/RobotStatechartContext.h +++ b/source/RobotAPI/core/RobotStatechartContext.h @@ -62,7 +62,7 @@ namespace armarx { public: // inherited from Component - virtual std::string getDefaultName() { return "RobotStatechartContext"; }; + virtual std::string getDefaultName() { return "RobotStatechartContext"; } virtual void onInitStatechartContext(); virtual void onConnectStatechartContext(); diff --git a/source/RobotAPI/motioncontrol/MotionControl.cpp b/source/RobotAPI/motioncontrol/MotionControl.cpp index ef91d7dd4a6bbe89301bd67dfc5f92d5357e3e8f..c52c05f1bd9019e307414614577acaf4d6b0abf2 100644 --- a/source/RobotAPI/motioncontrol/MotionControl.cpp +++ b/source/RobotAPI/motioncontrol/MotionControl.cpp @@ -15,13 +15,13 @@ using namespace armarx; using namespace armarx::MotionControl; -MotionControlHandler::MotionControlHandler() +MotionControlOfferer::MotionControlOfferer() { } -void MotionControlHandler::onInitRemoteStateOfferer() +void MotionControlOfferer::onInitRemoteStateOfferer() { //addState<MoveJoints>("MoveJoints"); //addState<MotionControlTestState>("MotionControlTestState"); @@ -30,7 +30,7 @@ void MotionControlHandler::onInitRemoteStateOfferer() -void MotionControlHandler::onConnectRemoteStateOfferer() +void MotionControlOfferer::onConnectRemoteStateOfferer() { } @@ -40,16 +40,16 @@ void MoveJoints::defineParameters() { context = getContext<RobotStatechartContext>(); - setConfigFile("RobotAPI/data/stateconfigs/MotionControl.xml"); + //setConfigFile("RobotAPI/data/stateconfigs/MotionControl.xml"); addToInput("jointNames", VariantType::List(VariantType::String), false); - addToInput("targetJointValues", VariantType::Float, false); + addToInput("targetJointValues", VariantType::List(VariantType::Float), false); // TODO: add when we have decided how to do it addToInput("jointMaxSpeeds", VariantType::List(VariantType::Float), true); addToInput("jointMaxSpeed", VariantType::List(VariantType::Float), true); - addToInput("targetTolerance", VariantType::Float, false); + addToInput("jointTargetTolerance", VariantType::Float, false); addToInput("timeoutInMs", VariantType::Int, false); @@ -69,7 +69,9 @@ void MoveJoints::onEnter() throw LocalException("Sizes of joint name list and joint value list do not match!"); } - for(int i=0; i<jointNames->getSize(); i++ ) + ARMARX_LOG << "number of joints that will be set: " << jointNames->getSize() << flush; + + for (int i=0; i<jointNames->getSize(); i++) { targetJointAngles[jointNames->getVariant(i)->getString()] = targetJointValues->getVariant(i)->getFloat(); ARMARX_VERBOSE << "setting joint angle for joint '" << jointNames->getVariant(i)->getString() << "' to " << targetJointValues->getVariant(i)->getFloat() << std::endl; @@ -80,14 +82,15 @@ void MoveJoints::onEnter() //ExpressionPtr cond = Expression::create(); Term cond; - float tolerance = getInput<float>("targetTolerance"); - for(int i=0; i<jointNames->getSize(); i++ ) + float tolerance = getInput<float>("jointTargetTolerance"); + for (int i=0; i<jointNames->getSize(); i++) { + //ARMARX_VERBOSE << "creating condition (" << i << " of " << jointNames->getSize() << ")" << flush; ParameterList inrangeCheck; inrangeCheck.push_back(new Variant(targetJointValues->getVariant(i)->getFloat()-tolerance)); inrangeCheck.push_back(new Variant(targetJointValues->getVariant(i)->getFloat()+tolerance)); - Literal inrangeLiteral(DataFieldIdentifier(context->getKinematicUnitObserverName(),"jointangles", jointNames->getVariant(i)->getString()), "inrange", inrangeCheck); + Literal inrangeLiteral(DataFieldIdentifier(context->getKinematicUnitObserverName(), "jointangles", jointNames->getVariant(i)->getString()), "inrange", inrangeCheck); cond = cond && inrangeLiteral; } @@ -135,7 +138,7 @@ void MoveJointsVelocityControl::defineParameters() { context = getContext<RobotStatechartContext>(); - setConfigFile("RobotAPI/data/stateconfigs/MotionControl.xml"); + //setConfigFile("RobotAPI/data/stateconfigs/MotionControl.xml"); addToInput("jointNames", VariantType::List(VariantType::String), false); addToInput("targetJointVelocities", VariantType::List(VariantType::Float), false); @@ -170,7 +173,7 @@ void MoveJointsVelocityControl::onEnter() for(int i=0; i<jointNames->getSize(); i++) { targetJointVelocities[jointNames->getVariant(i)->getString()] = targetVelocitiesValues->getVariant(i)->getFloat(); - ARMARX_VERBOSE << "setting joint angle for joint '" << jointNames->getVariant(i)->getString() << "' to " << targetVelocitiesValues->getVariant(i)->getFloat() << std::endl; + ARMARX_VERBOSE << "setting joint velocity for joint '" << jointNames->getVariant(i)->getString() << "' to " << targetVelocitiesValues->getVariant(i)->getFloat() << std::endl; } // TODO: Set Max Velocities @@ -225,7 +228,7 @@ void MoveTCPPoseIK::defineParameters() { context = getContext<RobotStatechartContext>(); - setConfigFile("RobotAPI/data/stateconfigs/MotionControl.xml"); + //setConfigFile("RobotAPI/data/stateconfigs/MotionControl.xml"); addToInput("kinematicChainName", VariantType::String, false); addToInput("targetTCPPosition", VariantType::FramedPosition, false); @@ -237,6 +240,7 @@ void MoveTCPPoseIK::defineParameters() addToInput("targetOrientationDistanceTolerance", VariantType::Float, false); addToInput("timeoutInMs", VariantType::Int, false); + addToInput("jointTargetTolerance", VariantType::Float, false); addToOutput("TCPDistanceToTarget", VariantType::Float, true); addToOutput("TCPOrientationDistanceToTarget", VariantType::Float, true); @@ -260,12 +264,13 @@ void MoveTCPPoseIK::onExit() void MoveTCPPoseIK::defineSubstates() { - StatePtr moveJoints = addState<MoveJoints>("MoveJoints"); StatePtr calculateJointAngleConfiguration = addState<CalculateJointAngleConfiguration>("CalculateJointAngleConfiguration"); + StatePtr moveJoints = addState<MoveJoints>("MoveJoints"); StatePtr validateJointAngleConfiguration = addState<ValidateJointAngleConfiguration>("ValidateJointAngleConfiguration"); StatePtr movingDone = addState<SuccessState>("movingDone") ; StatePtr movingFailed = addState<FailureState>("movingFailed") ; - setInitState(calculateJointAngleConfiguration, PM::createMapping()->mapFromParent("*","*")); + + setInitState(calculateJointAngleConfiguration, createMapping()->mapFromParent("*","*")); // PM::createMapping()->mapFromParent("*","*") ?? addTransition<EvCalculationDone>(calculateJointAngleConfiguration, moveJoints, createMapping()->mapFromParent("*","*")->mapFromOutput("*","*")); addTransition<EvJointTargetReached>(moveJoints, validateJointAngleConfiguration, createMapping()->mapFromParent("*","*")->mapFromOutput("*","*")); addTransition<EvSuccess>(validateJointAngleConfiguration, movingDone, createMapping()->mapFromOutput("*","*")); @@ -279,7 +284,7 @@ void MoveTCPTrajectory::defineParameters() { context = getContext<RobotStatechartContext>(); - setConfigFile("RobotAPI/data/stateconfigs/MotionControl.xml"); + //setConfigFile("RobotAPI/data/stateconfigs/MotionControl.xml"); addToInput("kinematicChainName", VariantType::String, false); addToInput("targetTCPPositions", VariantType::List(VariantType::FramedPosition), false); @@ -320,7 +325,7 @@ void MoveTCPTrajectory::onEnter() void MoveTCPTrajectory::onExit() { removeTimeoutEvent(timeoutEvent); - ChannelRefPtr r = getLocal<ChannelRefPtr>("trajectoryPointCounterID"); + ChannelRefPtr r = getLocal<ChannelRef>("trajectoryPointCounterID"); getContext()->systemObserverPrx->removeCounter(r); //removeCounterEvent(trajectoryPointCounterID); } @@ -461,12 +466,13 @@ void MoveTCPTrajectoryNextPoint::defineSubstates() void CalculateJointAngleConfiguration::defineParameters() { - addToInput("KinematicChainName", VariantType::String, false); + addToInput("kinematicChainName", VariantType::String, false); addToInput("targetTCPPosition", VariantType::FramedPosition, false); addToInput("targetTCPOrientation", VariantType::FramedOrientation, false); + addToInput("targetPositionDistanceTolerance", VariantType::Float, false); - addToOutput("jointNames", VariantType::String, true); - addToOutput("targetJointValues", VariantType::Float, true); + addToOutput("jointNames", VariantType::List(VariantType::String), true); + addToOutput("targetJointValues", VariantType::List(VariantType::Float), true); } @@ -475,15 +481,17 @@ void CalculateJointAngleConfiguration::run() { RobotStatechartContext* context = getContext<RobotStatechartContext>(); VirtualRobot::RobotPtr robotPtr(new RemoteRobot(context->robotStateComponent->getRobotSnapshot("CalculateTCPPoseTime"))); + + // TODO: with the following line, the IK doesn't find a solution, so this terrible hack must be used. Fix it!!! + //VirtualRobot::RobotPtr robot = robotPtr->clone("CalculateTCPPoseClone"); std::string robotModelFile; - ArmarXDataPath::getAbsolutePath("Armar4/data/Armar4/ArmarIV.xml", robotModelFile); + //ArmarXDataPath::getAbsolutePath("Armar4/data/Armar4/ArmarIV.xml", robotModelFile); + ArmarXDataPath::getAbsolutePath("Armar3/data/robotmodel/ArmarIII.xml", robotModelFile); VirtualRobot::RobotPtr robot = VirtualRobot::RobotIO::loadRobot(robotModelFile.c_str()); - //VirtualRobot::RobotConfigPtr configPtr(new VirtualRobot::RobotConfig(robotPtr, "blub")); - //robotPtr->getRobotNodeSet("Root")->getJointValues(configPtr); - //robot->setJointValues(robotPtr->getRobotNodeSet("Root"), robotPtr->getRobotNodeSet("Root")->getJointValues()); - VirtualRobot::GenericIKSolverPtr ikSolver(new VirtualRobot::GenericIKSolver(robot->getRobotNodeSet(getInput<std::string>("KinematicChainName")))); + VirtualRobot::GenericIKSolverPtr ikSolver(new VirtualRobot::GenericIKSolver(robot->getRobotNodeSet(getInput<std::string>("kinematicChainName")))); ikSolver->setVerbose(true); + ikSolver->setMaximumError(getInput<float>("targetPositionDistanceTolerance")); VirtualRobot::LinkedCoordinate target = ArmarPose::createLinkedCoordinate(robot, getInput<FramedPosition>("targetTCPPosition"), getInput<FramedOrientation>("targetTCPOrientation")); Eigen::Matrix4f goalInRoot = target.getInFrame(robot->getRootNode()); @@ -507,14 +515,18 @@ void CalculateJointAngleConfiguration::run() SingleTypeVariantList jointNames = SingleTypeVariantList(VariantType::String); SingleTypeVariantList targetJointValues = SingleTypeVariantList(VariantType::Float); - VirtualRobot::RobotNodeSetPtr kinematicChain = robot->getRobotNodeSet(getInput<std::string>("KinematicChainName") ); + VirtualRobot::RobotNodeSetPtr kinematicChain = robot->getRobotNodeSet(getInput<std::string>("kinematicChainName") ); for (int i = 0; i < (signed int)kinematicChain->getSize(); i++) { jointNames.addVariant(Variant(kinematicChain->getNode(i)->getName())); targetJointValues.addVariant(Variant(kinematicChain->getNode(i)->getJointValue())); + ARMARX_LOG << " joint: " << kinematicChain->getNode(i)->getName() << " value: " << kinematicChain->getNode(i)->getJointValue() << flush; } - setOutput("targetJointValues",targetJointValues); - setOutput("jointNames",jointNames); + ARMARX_LOG << "number of joints to be set: " << jointNames.getSize() << flush; + ARMARX_LOG << "setting output: jointNames" << flush; + setOutput("jointNames", jointNames); + ARMARX_LOG << "setting output: targetJointValues" << flush; + setOutput("targetJointValues", targetJointValues); sendEvent<EvCalculationDone>(); } } @@ -542,7 +554,7 @@ void ValidateJointAngleConfiguration::onEnter() RobotStatechartContext* context = getContext<RobotStatechartContext>(); VirtualRobot::RobotPtr robot(new RemoteRobot(context->robotStateComponent->getRobotSnapshot("ValidateTCPPoseTime"))); VirtualRobot::LinkedCoordinate actualPose(robot); - actualPose.set(robot->getRobotNodeSet(getInput<std::string>("KinematicChainName"))->getTCP()->getName(), Vector3f(0,0,0)); + actualPose.set(robot->getRobotNodeSet(getInput<std::string>("kinematicChainName"))->getTCP()->getName(), Vector3f(0,0,0)); actualPose.changeFrame(robot->getRootNode()); Vector3f actualPosition = actualPose.getPosition(); Quaternionf actualOrientation(actualPose.getPose().block<3,3>(0,0)); @@ -575,14 +587,14 @@ void ValidateJointAngleConfiguration::onEnter() void MotionControlTestState::defineParameters() { - setConfigFile("RobotAPIConfigs/stateconfigs/MotionControl.xml"); + //setConfigFile("RobotAPIConfigs/stateconfigs/MotionControl.xml"); addToInput("jointNames", VariantType::List(VariantType::String), false); addToInput("targetJointValues", VariantType::List(VariantType::Float), false); addToInput("jointMaxSpeed", VariantType::Float, true); - addToInput("targetTolerance", VariantType::Float, false); + addToInput("jointTargetTolerance", VariantType::Float, false); addToInput("timeoutInMs", VariantType::Int, false); @@ -607,7 +619,7 @@ void MotionControlTestState::defineSubstates() void MotionControlTestStateIK::defineParameters() { - setConfigFile("RobotAPIConfigs/stateconfigs/MotionControl.xml"); + //setConfigFile("RobotAPIConfigs/stateconfigs/MotionControl.xml"); addToInput("kinematicChainName", VariantType::String, false); //addToInput("targetTCPPosition", VariantType::FramedPosition, false); diff --git a/source/RobotAPI/motioncontrol/MotionControl.h b/source/RobotAPI/motioncontrol/MotionControl.h index 9df288bd925ad7a067336ce2d3034ef1531919d8..47c97d2e378b7312c84461b9826a71c6d014bb93 100644 --- a/source/RobotAPI/motioncontrol/MotionControl.h +++ b/source/RobotAPI/motioncontrol/MotionControl.h @@ -47,7 +47,7 @@ namespace MotionControl - jointNames: the names of the joints to be moved - targetJointVelocities: the desired joint velocities - targetJointVelocityTolerance: tolerance defining how precisely the joint velocity has to be reached - - timeoutInMs: a timout after which the attempt is aborted + - timeoutInMs: a timeout after which the attempt is aborted Output parameters: - jointVelocitiesDistancesToTargets: the difference between the desired and actual joint velocities @@ -59,7 +59,7 @@ namespace MotionControl - targetTCPOrientation: the target orientation - targetPositionDistanceTolerance: tolerance for the position to decide if the motion was successfull - targetOrientationDistanceTolerance: tolerance for the orientation to decide if the motion was successfull - - timeoutInMs: a timout after which the motion is aborted + - timeoutInMs: a timeout after which the motion is aborted Output parameters: - TCPDistanceToTarget: kartesian distance between TCP and target position - TCPOrientationDistanceToTarget: the difference between desired and actual orientation of the TCP @@ -72,7 +72,7 @@ namespace MotionControl - targetTCPOrientations: the list of target orientations - targetPositionDistanceTolerance: tolerance for the position to decide if the motion was successfull - targetOrientationDistanceTolerance: tolerance for the orientation to decide if the motion was successfull - - timeoutInMs: a timout after which the motion is aborted + - timeoutInMs: a timeout after which the motion is aborted Output parameters: - TCPDistanceToTarget: kartesian distance between TCP and target position - TCPOrientationDistanceToTarget: the difference between desired and actual orientation of the TCP @@ -90,13 +90,13 @@ namespace MotionControl * i.e. direct and inverse kinematics for arbitrary kinematic chains and predefined * parts like the arms. */ - class MotionControlHandler : public RemoteStateOfferer<RobotStatechartContext> + class MotionControlOfferer : public RemoteStateOfferer<RobotStatechartContext> { public: - MotionControlHandler(); + MotionControlOfferer(); void onInitRemoteStateOfferer(); void onConnectRemoteStateOfferer(); - std::string getHandlerName() const { return "MotionControl"; } + std::string getStateOffererName() const { return "MotionControl"; } }; @@ -129,7 +129,7 @@ namespace MotionControl * \param jointNames the names of the joints to be moved * \param targetJointValues the desired joint values * \param targetTolerance tolerance defining how precisely the joint position has to be reached - * \param timeoutInMs a timout after which the attempt to move is aborted + * \param timeoutInMs a timeout after which the attempt to move is aborted */ struct MoveJoints : StateTemplate<MoveJoints> { @@ -145,11 +145,11 @@ namespace MotionControl /** * \ingroup MotionControl - * Move the joints of a kinematic chain to the desired values using velocity control. + * Set the velocities of the joints of a kinematic chain. * \param jointNames the names of the joints to be moved * \param targetJointVelocities the desired joint velocities * \param targetJointVelocityTolerance tolerance defining how precisely the joint velocity has to be reached - * \param timeoutInMs a timout after which the attempt is aborted + * \param timeoutInMs a timeout after which the attempt is aborted */ struct MoveJointsVelocityControl : StateTemplate<MoveJointsVelocityControl> { @@ -170,7 +170,7 @@ namespace MotionControl * \param targetTCPOrientation the target orientation * \param targetPositionDistanceTolerance tolerance for the position to decide if the motion was successfull * \param targetOrientationDistanceTolerance tolerance for the orientation to decide if the motion was successfull - * \param timeoutInMs a timout after which the motion is aborted + * \param timeoutInMs a timeout after which the motion is aborted */ struct MoveTCPPoseIK : StateTemplate<MoveTCPPoseIK> { @@ -195,7 +195,7 @@ namespace MotionControl * \param targetTCPOrientations the list of target orientations * \param targetPositionDistanceTolerance tolerance for the position to decide if the motion was successfull * \param targetOrientationDistanceTolerance tolerance for the orientation to decide if the motion was successfull - * \param timeoutInMs a timout after which the motion is aborted + * \param timeoutInMs a timeout after which the motion is aborted */ struct MoveTCPTrajectory : StateTemplate<MoveTCPTrajectory> { diff --git a/source/RobotAPI/units/CMakeLists.txt b/source/RobotAPI/units/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..50c02b62cac78eb3aeb48e831c13cda9125baf48 --- /dev/null +++ b/source/RobotAPI/units/CMakeLists.txt @@ -0,0 +1,39 @@ +armarx_set_target("RobotAPI Units Library: RobotAPIUnits") + + +find_package(Eigen3 QUIET) +find_package(Simox QUIET) + +armarx_build_if(Eigen3_FOUND "Eigen3 not available") +armarx_build_if(Simox_FOUND "Simox-VirtualRobot not available") + +if (ARMARX_BUILD) + include_directories(${Eigen3_INCLUDE_DIR}) + include_directories(${VirtualRobot_INCLUDE_DIRS}) + + set(LIB_NAME RobotAPIUnits) + set(LIB_VERSION 0.1.0) + set(LIB_SOVERSION 0) + + set(LIBS RobotAPIInterfaces RobotAPICore ArmarXInterfaces ArmarXCore ArmarXCoreObservers ArmarXCoreRemoteRobot ${VirtualRobot_LIBRARIES}) + + set(LIB_HEADERS + ForceTorqueObserver.h + TCPControlUnit.h + TCPControlUnitObserver.h + + ) + set(LIB_FILES + ForceTorqueObserver.cpp + TCPControlUnit.cpp + TCPControlUnitObserver.cpp + ) + + + add_library(${LIB_NAME} SHARED ${LIB_FILES} ${LIB_HEADERS}) + + library_settings("${LIB_NAME}" "${LIB_VERSION}" "${LIB_SOVERSION}" "${LIB_HEADERS}") + target_link_ice(${LIB_NAME}) + target_link_libraries(${LIB_NAME} ${LIBS}) +endif() + diff --git a/source/RobotAPI/units/ForceTorqueObserver.cpp b/source/RobotAPI/units/ForceTorqueObserver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dd43ebb29a7ad5e331d6aed852f6e672f196bbbc --- /dev/null +++ b/source/RobotAPI/units/ForceTorqueObserver.cpp @@ -0,0 +1,132 @@ +#include "ForceTorqueObserver.h" + +#include <Core/observers/checks/ConditionCheckUpdated.h> +#include <Core/observers/checks/ConditionCheckEquals.h> +#include <Core/observers/checks/ConditionCheckInRange.h> +#include <Core/observers/checks/ConditionCheckLarger.h> +#include <Core/observers/checks/ConditionCheckSmaller.h> +#include <Core/robotstate/remote/checks/ConditionCheckMagnitudeChecks.h> + +#include <Core/robotstate/remote/RobotStateObjectFactories.h> + +#define RAWFORCE "_rawforcevectors" +#define OFFSETFORCE "_forceswithoffsetvectors" +#define FILTEREDFORCE "_filteredforcesvectors" +#define RAWTORQUE "_rawtorquevectors" +#define OFFSETTORQUE "_torqueswithoffsetvectors" +#define FORCETORQUEVECTORS "_forceTorqueVectors" + + +using namespace armarx; + +ForceTorqueObserver::ForceTorqueObserver() +{ +} + +void ForceTorqueObserver::onInitObserver() +{ + usingTopic(getProperty<std::string>("ForceTorqueTopicName").getValue()); + + // register all checks + offerConditionCheck("updated", new ConditionCheckUpdated()); + offerConditionCheck("larger", new ConditionCheckLarger()); + offerConditionCheck("equals", new ConditionCheckEquals()); + offerConditionCheck("smaller", new ConditionCheckSmaller()); +// offerConditionCheck("magnitudeinrange", new ConditionCheckInRange()); + offerConditionCheck("magnitudelarger", new ConditionCheckMagnitudeLarger()); +// offerConditionCheck("magnitudesmaller", new ConditionCheckSmaller()); + + // register all channels +// offerChannel(FORCETORQUEVECTORS,"Force and Torque vectors on specific parts of the robot."); + +// offerChannel(RAWFORCE,"Forces on specific parts of the robot."); +// offerChannel(OFFSETFORCE,"Force Torques of specific parts of the robot with an offset."); +// offerChannel(FILTEREDFORCE,"Gaussian filtered force torques of specific parts of the robot."); + +// offerChannel(RAWTORQUE,"Torques on specific parts of the robot."); + +} + +void ForceTorqueObserver::onConnectObserver() +{ + + +} + +//void ForceTorqueObserver::reportForceRaw(const FramedVector3Map &newForces, const Ice::Current &) +//{ + +//} + +//void ForceTorqueObserver::reportForceWithOffset(const FramedVector3Map &newForces, const Ice::Current &) +//{ +// FramedVector3Map::const_iterator it = newForces.begin(); +// for(; it != newForces.end(); it++) +// { + +// FramedVector3Ptr vec = FramedVector3Ptr::dynamicCast(it->second); +// if(!existsDataField(OFFSETFORCE, it->first)) +// offerDataFieldWithDefault(OFFSETFORCE, it->first, Variant(it->second), "3D vector for Force Torques of " + it->first); +// else +// setDataField(OFFSETFORCE, it->first, Variant(it->second)); + + +// if(!existsChannel(it->first)) +// { +// offerChannel(it->first,"Force on " + it->first); +// offerDataFieldWithDefault(it->first,"force_x", Variant(vec->x), "Force on X axis"); +// offerDataFieldWithDefault(it->first,"force_y", Variant(vec->y), "Force on Y axis"); +// offerDataFieldWithDefault(it->first,"force_z", Variant(vec->z), "Force on Z axis"); +// } +// else +// { +// setDataField(it->first,"force_x", Variant(vec->x)); +// setDataField(it->first,"force_y", Variant(vec->y)); +// setDataField(it->first,"force_z", Variant(vec->z)); +// } + +// } +//} + + + +void ForceTorqueObserver::reportSensorValues(const std::string &type, const FramedVector3Map &newValues, const Ice::Current &) +{ + ScopedLock lock(dataMutex); + FramedVector3Map::const_iterator it = newValues.begin(); + if(!existsChannel(type)) + offerChannel(type, "Force and Torque vectors on specific parts of the robot."); + for(; it != newValues.end(); it++) + { + + FramedVector3Ptr vec = FramedVector3Ptr::dynamicCast(it->second); + std::string identifier = it->first + "_" + type + "_in_frame_" + vec->frame; + if(!existsDataField(type, identifier)) + offerDataFieldWithDefault(type, identifier, Variant(it->second), "3D vector for Force Torques of " + it->first); + else + setDataField(type, identifier, Variant(it->second)); + + if(!existsChannel(identifier)) + { + offerChannel(identifier,type + " on " + it->first); + offerDataFieldWithDefault(identifier,type + "_x", Variant(vec->x), type + " on X axis"); + offerDataFieldWithDefault(identifier,type + "_y", Variant(vec->y), type + " on Y axis"); + offerDataFieldWithDefault(identifier,type + "_z", Variant(vec->z), type + " on Z axis"); + offerDataFieldWithDefault(identifier,type + "_frame", Variant(vec->frame), "Frame of " + type); + } + else + { + setDataField(identifier,type + "_x", Variant(vec->x)); + setDataField(identifier,type + "_y", Variant(vec->y)); + setDataField(identifier,type + "_z", Variant(vec->z)); + setDataField(identifier,type + "_frame", Variant(vec->frame)); + } + + } +} + +PropertyDefinitionsPtr ForceTorqueObserver::createPropertyDefinitions() +{ + return PropertyDefinitionsPtr(new ForceTorqueObserverPropertyDefinitions( + getConfigIdentifier())); +} diff --git a/source/RobotAPI/units/ForceTorqueObserver.h b/source/RobotAPI/units/ForceTorqueObserver.h new file mode 100644 index 0000000000000000000000000000000000000000..8b9c34dc2276e7f88c74577ed65fbbaebd62e450 --- /dev/null +++ b/source/RobotAPI/units/ForceTorqueObserver.h @@ -0,0 +1,48 @@ +#ifndef _ARMARX_ROBOTAPI_FORCETORQUEOBSERVER_H +#define _ARMARX_ROBOTAPI_FORCETORQUEOBSERVER_H + +#include <RobotAPI/interface/units/ForceTorqueUnit.h> +#include <Core/observers/Observer.h> + +namespace armarx +{ + + class ForceTorqueObserverPropertyDefinitions: + public ComponentPropertyDefinitions + { + public: + ForceTorqueObserverPropertyDefinitions(std::string prefix): + ComponentPropertyDefinitions(prefix) + { + defineRequiredProperty<std::string>("ForceTorqueTopicName","Name of the ForceTorqueUnit Topic"); + } + }; + + class ForceTorqueObserver : + virtual public Observer, + virtual public ForceTorqueUnitObserverInterface + { + public: + ForceTorqueObserver(); + + // framework hooks + virtual std::string getDefaultName() const { return "ForceTorqueUnitObserver"; } + void onInitObserver(); + void onConnectObserver(); + + void reportSensorValues(const std::string & type, const ::armarx::FramedVector3Map& newForces, const ::Ice::Current& = ::Ice::Current()); +// void reportForceWithOffset(const ::armarx::FramedVector3Map& newForces, const ::Ice::Current& = ::Ice::Current()); +// void reportTorqueRaw(const ::armarx::FramedVector3Map& newTorques, const ::Ice::Current& = ::Ice::Current()); +// void reportTorqueWithOffset(const ::armarx::FramedVector3Map& newTorques, const ::Ice::Current& = ::Ice::Current()); + + /** + * @see PropertyUser::createPropertyDefinitions() + */ + virtual PropertyDefinitionsPtr createPropertyDefinitions(); + private: + armarx::Mutex dataMutex; + + }; +} + +#endif diff --git a/source/RobotAPI/units/TCPControlUnit.cpp b/source/RobotAPI/units/TCPControlUnit.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5f0123486f1bf598a746cbcd66397d93828eee71 --- /dev/null +++ b/source/RobotAPI/units/TCPControlUnit.cpp @@ -0,0 +1,485 @@ +/** +* This file is part of ArmarX. +* +* ArmarX is free software; you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as +* published by the Free Software Foundation; either version 2 of +* the License, or (at your option) any later version. +* +* 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 Lesser 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 2013 +* @copyright http://www.gnu.org/licenses/gpl.txt +* GNU General Public License +*/ + +#include "TCPControlUnit.h" +#include <Core/robotstate/remote/LinkedPose.h> + +#include <boost/unordered_map.hpp> + +#include <Core/core/exceptions/local/ExpressionException.h> + +#include <Core/core/system/ArmarXDataPath.h> +#include <VirtualRobot/RobotConfig.h> +#include <VirtualRobot/XML/RobotIO.h> + +using namespace VirtualRobot; + + + +namespace armarx +{ + + TCPControlUnit::TCPControlUnit() : + maxJointVelocity(30.f/180*3.141), + cycleTime(20) + { + + } + + void TCPControlUnit::onInitComponent() + { + usingProxy(getProperty<std::string>("KinematicUnitName").getValue()); + usingProxy("RobotStateComponent"); + offeringTopic("TCPControlUnitState"); + } + + + void TCPControlUnit::onConnectComponent() + { + ScopedLock lock(dataMutex); + if(getProperty<float>("MaxJointVelocity").isSet()) + maxJointVelocity = getProperty<float>("MaxJointVelocity").getValue(); + kinematicUnitPrx = getProxy<KinematicUnitInterfacePrx>(getProperty<std::string>("KinematicUnitName").getValue()); + robotStateComponentPrx = getProxy<RobotStateComponentInterfacePrx>("RobotStateComponent"); + + + + // retrieve Jacobian pseudo inverse for TCP and chain + remoteRobotPrx = robotStateComponentPrx->getSynchronizedRobot(); +// localRobot.reset(new RemoteRobot(remoteRobotPrx)); +// ARMARX_INFO << "hi limit : " << localRobot->getRobotNode("LeftArm_Joint1")->getJointLimitHi(); +// localRobot = localRobot->clone("localRobot"); +// ARMARX_INFO << "hi limit after: " << localRobot->getRobotNode("LeftArm_Joint1")->getJointLimitHi(); + + std::string robotFile = getProperty<std::string>("RobotFileName").getValue(); + if (!ArmarXDataPath::getAbsolutePath(robotFile,robotFile)) + { + throw UserException("Could not find robot file " + robotFile); + } + localRobot = VirtualRobot::RobotIO::loadRobot(robotFile, VirtualRobot::RobotIO::eStructure);//localRobot->clone("LocalRobot"); + localRobot->setUpdateVisualization(false); + localRobot->setThreadsafe(false); + + // dIK = new VirtualRobot::DifferentialIK(robotNodeSet); + + FramedVector3Ptr tcpVel = new FramedVector3(); + tcpVel->x = -30; + tcpVel->frame = "Root"; + FramedVector3Ptr tcpOriVel = new FramedVector3(); + tcpOriVel->frame = "Root"; + + // setTCPVelocity("TorsoLeftArm", tcpVel, NULL); + // setTCPVelocity("RightArm", tcpVel, NULL); + // setTCPVelocity("RightLeg", tcpVel, NULL); + // setTCPVelocity("LeftLeg", tcpVel, NULL); + // request(); + + listener = getTopic<TCPControlUnitListenerPrx>("TCPControlUnitState"); + topicTask = new PeriodicTask<TCPControlUnit>(this, &TCPControlUnit::periodicReport,cycleTime, false, "TCPDataProvider"); + topicTask->start(); + } + + void TCPControlUnit::onDisconnectComponent() + { + if(topicTask) + topicTask->stop(); + release(); + } + + void TCPControlUnit::onExitComponent() + { + } + + + + void TCPControlUnit::setCycleTime(Ice::Int milliseconds, const Ice::Current & c) + { + ScopedLock lock(taskMutex); + cycleTime = milliseconds; + if(execTask) + execTask->changeInterval(cycleTime); + } + + void TCPControlUnit::setTCPVelocity(const std::string &nodeSetName, const std::string &tcpName, const FramedVector3BasePtr &translationVelocity, const FramedVector3BasePtr &orientationVelocityRPY, const Ice::Current &c) + { + ScopedLock lock(dataMutex); + if(translationVelocity) + ARMARX_VERBOSE << "Setting new Velocity for " << nodeSetName << "\n" << FramedVector3Ptr::dynamicCast(translationVelocity)->toEigen(); + if(orientationVelocityRPY) + ARMARX_VERBOSE << "Orientation Velo: " << FramedVector3Ptr::dynamicCast(orientationVelocityRPY)->toEigen(); + TCPVelocityData data; + data.nodeSetName = nodeSetName; + data.translationVelocity = FramedVector3Ptr::dynamicCast(translationVelocity); + data.orientationVelocity = FramedVector3Ptr::dynamicCast(orientationVelocityRPY); + if(tcpName.empty()) + data.tcpName = localRobot->getRobotNodeSet(nodeSetName)->getTCP()->getName(); + else + data.tcpName = tcpName; + tcpVelocitiesMap[data.tcpName] = data; +// if(translationVelocity) +// targetTranslationVelocities[nodeSetName] = translationVelocity; +// if(orientationVelocityRPY) +// targetOrientationVelocitiesRPY[nodeSetName] = orientationVelocityRPY; + + } + + + void TCPControlUnit::init(const Ice::Current & c) + { + } + + void TCPControlUnit::start(const Ice::Current & c) + { + } + + void TCPControlUnit::stop(const Ice::Current & c) + { + } + + UnitExecutionState TCPControlUnit::getExecutionState(const Ice::Current & c) + { + switch (getState()) + { + case eManagedIceObjectStarted: + return eUnitStarted; + case eManagedIceObjectInitialized: + case eManagedIceObjectStarting: + return eUnitInitialized; + case eManagedIceObjectExiting: + case eManagedIceObjectExited: + return eUnitStopped; + default: + return eUnitConstructed; + } + } + + void TCPControlUnit::request(const Ice::Current & c) + { + ScopedLock lock(taskMutex); + int cycleTime; + { + cycleTime = this->cycleTime; + } + ARMARX_IMPORTANT << "Requesting TCPControlUnit"; + if(execTask) + execTask->stop(); + execTask = new PeriodicTask<TCPControlUnit>(this, &TCPControlUnit::periodicExec, cycleTime, true, "TCPVelocityCalculator"); + execTask->start(); + ARMARX_IMPORTANT << "Requested TCPControlUnit"; + } + + void TCPControlUnit::release(const Ice::Current & c) + { + ScopedLock lock(taskMutex); + ARMARX_IMPORTANT << "Releasing TCPControlUnit"; + if(execTask) + execTask->stop(); + kinematicUnitPrx->stop(); + ARMARX_IMPORTANT << "Released TCPControlUnit"; + + } + + void TCPControlUnit::periodicExec() + { + ARMARX_INFO << deactivateSpam(4) << "periodicExec for " << tcpVelocitiesMap.size(); +// IceUtil::Time startTime = IceUtil::Time::now(); + + ScopedLock lock(dataMutex); + + NameValueMap robotConfigMap = remoteRobotPrx->getConfig(); +// NameValueMap::iterator it = robotConfigMap.begin(); + std::map<std::string, float> jointValues(robotConfigMap.begin(), robotConfigMap.end()); + + localRobot->setJointValues(jointValues); + +// dIKMap.clear(); + TCPVelocityDataMap::iterator it = tcpVelocitiesMap.begin(); + for(; it != tcpVelocitiesMap.end(); it++) + { + const TCPVelocityData& data = it->second; + RobotNodeSetPtr nodeSet = localRobot->getRobotNodeSet(data.nodeSetName); + std::string refFrame = nodeSet->getTCP()->getName(); + DIKMap::iterator itDIK = dIKMap.find(data.nodeSetName); + if(itDIK == dIKMap.end()) + dIKMap[data.nodeSetName].reset(new EDifferentialIK(nodeSet, localRobot->getRootNode()/*, VirtualRobot::JacobiProvider::eTranspose*/)); + boost::shared_dynamic_cast<EDifferentialIK>(dIKMap[data.nodeSetName])->clearGoals(); + } + + using namespace Eigen; + + it = tcpVelocitiesMap.begin(); + for(; it != tcpVelocitiesMap.end(); it++) + { + + TCPVelocityData& data = it->second; + RobotNodeSetPtr nodeSet = localRobot->getRobotNodeSet(data.nodeSetName); + std::string refFrame = localRobot->getRootNode()->getName(); + + IKSolver::CartesianSelection mode; + if(data.translationVelocity && data.orientationVelocity) + { + mode = IKSolver::All; +// ARMARX_INFO << deactivateSpam(4) << "FullMode"; + } + else if(data.translationVelocity && !data.orientationVelocity) + mode = IKSolver::Position; + else if(!data.translationVelocity && data.orientationVelocity) + mode = IKSolver::Orientation; + else + { +// ARMARX_VERBOSE << deactivateSpam(2) << "No mode feasible for " << data.nodeSetName << " - skipping"; + continue; + } + + RobotNodePtr tcpNode = localRobot->getRobotNode(data.tcpName); + Eigen::Matrix4f m; + m.setIdentity(); + + if(data.orientationVelocity) + { + data.orientationVelocity = FramedVector3::ChangeFrame(localRobot, *data.orientationVelocity, refFrame); +// ARMARX_INFO << deactivateSpam(1) << "Orientation in " << refFrame << ": " << data.orientationVelocity->toEigen(); + Eigen::Matrix3f rot; + rot = Eigen::AngleAxisf(data.orientationVelocity->z, Eigen::Vector3f::UnitZ()) + * Eigen::AngleAxisf(data.orientationVelocity->y, Eigen::Vector3f::UnitY()) + * Eigen::AngleAxisf(data.orientationVelocity->x, Eigen::Vector3f::UnitX()); + m.block(0,0,3,3) = rot * tcpNode->getGlobalPose().block(0,0,3,3); + + } + +// ARMARX_VERBOSE << deactivateSpam(1) << "Delta Mat: \n" << m; + + +// m = m * tcpNode->getGlobalPose(); + + if(data.translationVelocity) + { + data.translationVelocity = FramedVector3::ChangeFrame(localRobot, *data.translationVelocity, refFrame); +// ARMARX_INFO << deactivateSpam(1) << "Translation in " << refFrame << ": " << data.translationVelocity->toEigen(); + m.block(0,3,3,1) = tcpNode->getGlobalPose().block(0,3,3,1) + data.translationVelocity->toEigen(); + } + + + DifferentialIKPtr dIK = dIKMap[data.nodeSetName]; + if(!dIK) + { + ARMARX_WARNING << deactivateSpam(1) << "DiffIK is NULL for robot node set: " << data.nodeSetName; + continue; + } +// ARMARX_VERBOSE << deactivateSpam(1) << "Old Pos: \n" << tcpNode->getGlobalPose(); +// ARMARX_VERBOSE << deactivateSpam(1) << "New Goal: \n" << m; + dIK->setGoal(m, tcpNode,mode); + +// ARMARX_VERBOSE << deactivateSpam(1) << "Delta to Goal: " << dIK->getDeltaToGoal(tcpNode); + } + + + NameValueMap targetVelocities; + NameControlModeMap controlModes; + DIKMap::iterator itDIK = dIKMap.begin(); + for(; itDIK != dIKMap.end(); itDIK++) + { + RobotNodeSetPtr robotNodeSet = localRobot->getRobotNodeSet(itDIK->first); + EDifferentialIKPtr dIK = boost::shared_dynamic_cast<EDifferentialIK>(itDIK->second); + Eigen::VectorXf jointDelta = dIK->computeStep(1.0); + + MatrixXf fullJac = dIK->calcFullJacobian(); + MatrixXf fullJacInv = dIK->computePseudoInverseJacobianMatrix(fullJac); + Eigen::VectorXf jointLimitCompensation = CalcJointLimitAvoidanceDeltas(robotNodeSet,fullJac, fullJacInv); + jointDelta += jointLimitCompensation; + + jointDelta = applyMaxJointVelocity(jointDelta, maxJointVelocity); + + Eigen::Vector3f currentTCPPosition = robotNodeSet->getTCP()->getGlobalPose().block(0,3,3,1); + // ARMARX_INFO << "Current TCP Position: \n" << currentTCPPosition; + ARMARX_VERBOSE << deactivateSpam(2)<< "ActualTCPVelocity: " << (currentTCPPosition - lastTCPPose.block(0,3,3,1))/(0.001*cycleTime); + lastTCPPose = robotNodeSet->getTCP()->getGlobalPose(); + + // build name value map + + const std::vector< VirtualRobot::RobotNodePtr > nodes = robotNodeSet->getAllRobotNodes(); + std::vector< VirtualRobot::RobotNodePtr >::const_iterator iter = nodes.begin(); + int i = 0; + while (iter != nodes.end() && i < jointDelta.rows()) + { + if(targetVelocities.find((*iter)->getName()) != targetVelocities.end()) + ARMARX_WARNING << deactivateSpam(2) << (*iter)->getName() << " is set from two joint delta calculations - overwriting first value"; + targetVelocities.insert(std::make_pair((*iter)->getName(), jointDelta(i))); + + controlModes.insert(std::make_pair((*iter)->getName(), eVelocityControl)); + i++; + iter++; + }; + } + + + + + kinematicUnitPrx->switchControlMode(controlModes); + kinematicUnitPrx->setJointVelocities(targetVelocities); + + + + } + + void TCPControlUnit::periodicReport() + { + ScopedLock lock(dataMutex); + + NameValueMap robotConfigMap = remoteRobotPrx->getConfig(); +// NameValueMap::iterator it = robotConfigMap.begin(); + std::map<std::string, float> jointValues(robotConfigMap.begin(), robotConfigMap.end()); + + localRobot->setJointValues(jointValues); + std::vector<RobotNodeSetPtr > nodeSets = localRobot->getRobotNodeSets(); + FramedPoseBaseMap tcpPoses; + std::string rootFrame = localRobot->getRootNode()->getName(); + for(unsigned int i=0; i < nodeSets.size(); i++) + { + RobotNodeSetPtr nodeSet = nodeSets.at(i); + tcpPoses[nodeSet->getTCP()->getName()]= new FramedPose(nodeSet->getTCP()->getGlobalPose(),rootFrame); + } + listener->reportTCPPose(tcpPoses); + } + + + Eigen::VectorXf TCPControlUnit::CalcJointLimitAvoidanceDeltas(VirtualRobot::RobotNodeSetPtr robotNodeSet, const Eigen::MatrixXf& jacobian, const Eigen::MatrixXf& jacobianInverse, Eigen::VectorXf desiredJointValues) + { + + std::vector< VirtualRobot::RobotNodePtr > nodes = robotNodeSet->getAllRobotNodes(); + Eigen::VectorXf actualJointValues(nodes.size()); + if(desiredJointValues.rows() == 0) + { + + desiredJointValues.resize(nodes.size()); + + for(unsigned int i=0; i < nodes.size(); i++) + { + VirtualRobot::RobotNodePtr node = nodes.at(i); + desiredJointValues(i) = (node->getJointLimitHigh() - node->getJointLimitLow()) * 0.5f + node->getJointLimitLow(); + } + + + } +// ARMARX_IMPORTANT << deactivateSpam(true, 0.5) << "desiredJointValues: " << desiredJointValues; + Eigen::VectorXf jointCompensationDeltas(desiredJointValues.rows()); + for(unsigned int i = 0; i < desiredJointValues.rows(); i++) + { + VirtualRobot::RobotNodePtr node = nodes.at(i); + actualJointValues(i) = node->getJointValue(); + jointCompensationDeltas(i) = (node->getJointValue() - desiredJointValues(i) ) / (node->getJointLimitHigh() - node->getJointLimitLow()); + jointCompensationDeltas(i) = -pow(jointCompensationDeltas(i), 3)*pow(nodes.size()-i,2); + } +// ARMARX_IMPORTANT << deactivateSpam(true, 0.5) << "actualJointValues: " << actualJointValues; + + return CalcNullspaceJointDeltas(jointCompensationDeltas,jacobian, jacobianInverse); + } + + Eigen::VectorXf TCPControlUnit::CalcNullspaceJointDeltas(const Eigen::VectorXf& desiredJointDeltas, const Eigen::MatrixXf& jacobian, const Eigen::MatrixXf& jacobianInverse) + { + Eigen::MatrixXf I(jacobianInverse.rows(),jacobian.cols()); + I.setIdentity(); + + Eigen::MatrixXf nullspaceProjection = I - jacobianInverse * jacobian; + + Eigen::VectorXf delta = nullspaceProjection * desiredJointDeltas; + return delta; + } + + Eigen::VectorXf TCPControlUnit::applyMaxJointVelocity(const Eigen::VectorXf& jointVelocity, float maxJointVelocity) + { + float currentMaxJointVel = std::numeric_limits<float>::min(); + unsigned int rows = jointVelocity.rows(); + for(unsigned int i=0; i < rows; i++) + { + currentMaxJointVel = std::max(jointVelocity(i), currentMaxJointVel); + } + + if(currentMaxJointVel > maxJointVelocity) + { + ARMARX_WARNING << deactivateSpam(1) << "max joint velocity too high: " << currentMaxJointVel << " allowed: " << maxJointVelocity; + return jointVelocity * (maxJointVelocity/currentMaxJointVel); + } + else + return jointVelocity; + + } + + + PropertyDefinitionsPtr TCPControlUnit::createPropertyDefinitions() + { + + return PropertyDefinitionsPtr(new TCPControlUnitPropertyDefinitions( + getConfigIdentifier())); + } + + EDifferentialIK::EDifferentialIK(RobotNodeSetPtr rns, RobotNodePtr coordSystem, JacobiProvider::InverseJacobiMethod invJacMethod) : + DifferentialIK(rns, coordSystem, invJacMethod) + { + + } + + Eigen::MatrixXf EDifferentialIK::calcFullJacobian() + { + if (nRows==0) this->setNRows(); + size_t nDoF = nodes.size(); + + using namespace Eigen; + MatrixXf Jacobian(nRows,nDoF); + + size_t index=0; + for (size_t i=0; i<tcp_set.size();i++) + { + RobotNodePtr tcp = tcp_set[i]; + if (this->targets.find(tcp)!=this->targets.end()) + { + IKSolver::CartesianSelection mode = this->modes[tcp]; + MatrixXf partJacobian = this->getJacobianMatrix(tcp,mode); + Jacobian.block(index,0,partJacobian.rows(),nDoF) = partJacobian; + } + else + VR_ERROR << "Internal error?!" << endl; // Error + + + } + return Jacobian; + + } + + void EDifferentialIK::clearGoals() + { + targets.clear(); + modes.clear(); + tolerancePosition.clear(); + toleranceRotation.clear(); + parents.clear(); + } + + void EDifferentialIK::setRefFrame(RobotNodePtr coordSystem) + { + this->coordSystem = coordSystem; + } + + +} + diff --git a/source/RobotAPI/units/TCPControlUnit.h b/source/RobotAPI/units/TCPControlUnit.h new file mode 100644 index 0000000000000000000000000000000000000000..d66e04be6b015669238fc104ab18c48d27a1e5d3 --- /dev/null +++ b/source/RobotAPI/units/TCPControlUnit.h @@ -0,0 +1,145 @@ +/** +* This file is part of ArmarX. +* +* ArmarX is free software; you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as +* published by the Free Software Foundation; either version 2 of +* the License, or (at your option) any later version. +* +* 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 Lesser 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 2013 +* @copyright http://www.gnu.org/licenses/gpl.txt +* GNU General Public License +*/ + +#ifndef _ARMARX_TCPCONTROLUNIT_H +#define _ARMARX_TCPCONTROLUNIT_H + +#include <RobotAPI/interface/units/TCPControlUnit.h> +#include <Core/robotstate/remote/ArmarPose.h> +#include <Core/core/services/tasks/PeriodicTask.h> +#include <Core/core/Component.h> + +#include <VirtualRobot/IK/DifferentialIK.h> +#include <Core/robotstate/remote/RemoteRobot.h> + +namespace armarx { + + + class TCPControlUnitPropertyDefinitions: + public ComponentPropertyDefinitions + { + public: + TCPControlUnitPropertyDefinitions(std::string prefix): + ComponentPropertyDefinitions(prefix) + { + defineRequiredProperty<std::string>("KinematicUnitName","Name of the KinematicUnit Proxy"); + defineOptionalProperty<float>("MaxJointVelocity",30.f/180*3.141, "Maximal joint velocity in rad/sec"); + defineRequiredProperty<std::string>("RobotFileName", "Robot file name, e.g. robot_model.xml"); + + } + }; + + class TCPControlUnit : + virtual public Component, + virtual public TCPControlUnitInterface + { + public: + TCPControlUnit(); + + + void onInitComponent(); + void onConnectComponent(); + void onDisconnectComponent(); + void onExitComponent(); + std::string getDefaultName() const{return "TCPControlUnit";} + + // TCPControlUnitInterface interface + + void setCycleTime(Ice::Int milliseconds, const Ice::Current &c = Ice::Current()); + void setTCPVelocity(const std::string &nodeSetName, const std::string &tcpName, const::armarx::FramedVector3BasePtr &translationVelocity, const::armarx::FramedVector3BasePtr &orientationVelocityRPY, const Ice::Current &c = Ice::Current()); + + // UnitExecutionManagementInterface interface + void init(const Ice::Current &c = Ice::Current()); + void start(const Ice::Current &c = Ice::Current()); + void stop(const Ice::Current &c = Ice::Current()); + UnitExecutionState getExecutionState(const Ice::Current &c = Ice::Current()); + + // UnitResourceManagementInterface interface + void request(const Ice::Current &c = Ice::Current()); + void release(const Ice::Current &c = Ice::Current()); + + // PropertyUser interface + PropertyDefinitionsPtr createPropertyDefinitions(); + + static Eigen::VectorXf CalcNullspaceJointDeltas(const Eigen::VectorXf &desiredJointDeltas, const Eigen::MatrixXf &jacobian, const Eigen::MatrixXf &jacobianInverse); + static Eigen::VectorXf CalcJointLimitAvoidanceDeltas(VirtualRobot::RobotNodeSetPtr robotNodeSet, const Eigen::MatrixXf &jacobian, const Eigen::MatrixXf &jacobianInverse, Eigen::VectorXf desiredJointValues = Eigen::VectorXf()); + private: + void periodicExec(); + void periodicReport(); + Eigen::VectorXf calcJointVelocities(VirtualRobot::RobotNodeSetPtr robotNodeSet, Eigen::VectorXf tcpDelta, VirtualRobot::RobotNodePtr refFrame, VirtualRobot::IKSolver::CartesianSelection mode); + Eigen::VectorXf applyMaxJointVelocity(const Eigen::VectorXf &jointVelocity, float maxJointVelocity); + + float maxJointVelocity; + int cycleTime; + Eigen::Matrix4f lastTCPPose; + + struct TCPVelocityData + { + FramedVector3Ptr translationVelocity; + FramedVector3Ptr orientationVelocity; + std::string nodeSetName; + std::string tcpName; + }; + + typedef std::map<std::string, TCPVelocityData> TCPVelocityDataMap; + TCPVelocityDataMap tcpVelocitiesMap; + + typedef std::map<std::string, VirtualRobot::DifferentialIKPtr> DIKMap; + DIKMap dIKMap; +// FramedVector3Map targetTranslationVelocities; +// FramedVector3Map targetOrientationVelocitiesRPY; + + PeriodicTask<TCPControlUnit>::pointer_type execTask; + PeriodicTask<TCPControlUnit>::pointer_type topicTask; + + RobotStateComponentInterfacePrx robotStateComponentPrx; + KinematicUnitInterfacePrx kinematicUnitPrx; + SharedRobotInterfacePrx remoteRobotPrx; + VirtualRobot::RobotPtr localRobot; + TCPControlUnitListenerPrx listener; +// VirtualRobot::RobotNodeSetPtr robotNodeSet; +// VirtualRobot::DifferentialIKPtr dIK; + + Mutex dataMutex; + Mutex taskMutex; + + }; + + class EDifferentialIK : public VirtualRobot::DifferentialIK + { + public: + EDifferentialIK(VirtualRobot::RobotNodeSetPtr rns,VirtualRobot:: RobotNodePtr coordSystem = VirtualRobot::RobotNodePtr(), VirtualRobot::JacobiProvider::InverseJacobiMethod invJacMethod = eSVD); + + VirtualRobot::RobotNodePtr getRefFrame(){return coordSystem;} + int getJacobianRows(){ return nRows;} + + Eigen::MatrixXf calcFullJacobian(); + + void clearGoals(); + void setRefFrame(VirtualRobot:: RobotNodePtr coordSystem); + }; + typedef boost::shared_ptr<EDifferentialIK> EDifferentialIKPtr; + +} + +#endif diff --git a/source/RobotAPI/units/TCPControlUnitObserver.cpp b/source/RobotAPI/units/TCPControlUnitObserver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..20ae2d59ecdfecab25d2a9681d052aa732ec8e75 --- /dev/null +++ b/source/RobotAPI/units/TCPControlUnitObserver.cpp @@ -0,0 +1,117 @@ +/** +* This file is part of ArmarX. +* +* ArmarX is free software; you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as +* published by the Free Software Foundation; either version 2 of +* the License, or (at your option) any later version. +* +* 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 Lesser 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 2013 +* @copyright http://www.gnu.org/licenses/gpl.txt +* GNU General Public License +*/ + +#include "TCPControlUnitObserver.h" + +//#include <Core/robotstate/remote/checks/ConditionCheckEqualsPoseWithTolerance.h> +#include <Core/observers/checks/ConditionCheckUpdated.h> +#include <Core/observers/checks/ConditionCheckEquals.h> +#include <Core/observers/checks/ConditionCheckInRange.h> +#include <Core/observers/checks/ConditionCheckLarger.h> +#include <Core/observers/checks/ConditionCheckSmaller.h> +#include <Core/robotstate/remote/checks/ConditionCheckMagnitudeChecks.h> + +namespace armarx { + + TCPControlUnitObserver::TCPControlUnitObserver() + { + } + + void TCPControlUnitObserver::onInitObserver() + { + usingTopic(getProperty<std::string>("TCPControlUnitName").getValue() + "State"); + + // register all checks + offerConditionCheck("updated", new ConditionCheckUpdated()); + offerConditionCheck("larger", new ConditionCheckLarger()); + offerConditionCheck("equals", new ConditionCheckEquals()); + offerConditionCheck("smaller", new ConditionCheckSmaller()); + // offerConditionCheck("magnitudeinrange", new ConditionCheckInRange()); + offerConditionCheck("magnitudelarger", new ConditionCheckMagnitudeLarger()); +// offerConditionCheck("equalsPoseWithTol", new ConditionCheckEqualsPoseWithTolerance()); + + + offerChannel("TCPPose", "TCP poses of the robot."); + offerChannel("TCPVelocities", "TCP velocities of the robot."); + + } + + void TCPControlUnitObserver::onConnectObserver() + { + + } + + PropertyDefinitionsPtr TCPControlUnitObserver::createPropertyDefinitions() + { + return PropertyDefinitionsPtr(new TCPControlUnitObserverPropertyDefinitions( + getConfigIdentifier())); + } + + void TCPControlUnitObserver::reportTCPPose(const FramedPoseBaseMap &poseMap, const Ice::Current &) + { + ScopedLock lock(dataMutex); + FramedPoseBaseMap::const_iterator it = poseMap.begin(); + for(; it != poseMap.end(); it++) + { + + FramedPosePtr vec = FramedPosePtr::dynamicCast(it->second); + const std::string &tcpName = it->first; + if(!existsDataField("TCPPose", tcpName)) + offerDataFieldWithDefault("TCPPose", tcpName, Variant(it->second), "Pose of " + tcpName); + else + setDataField("TCPPose", tcpName, Variant(it->second)); + + if(!existsChannel(tcpName)) + { + offerChannel(tcpName, "pose components of " + tcpName); + offerDataFieldWithDefault(tcpName,"x", Variant(vec->position->x), "X axis"); + offerDataFieldWithDefault(tcpName,"y", Variant(vec->position->y), "Y axis"); + offerDataFieldWithDefault(tcpName,"z", Variant(vec->position->z), "Z axis"); + offerDataFieldWithDefault(tcpName,"qx", Variant(vec->orientation->qx), "Quaternion part x"); + offerDataFieldWithDefault(tcpName,"qy", Variant(vec->orientation->qy), "Quaternion part y"); + offerDataFieldWithDefault(tcpName,"qz", Variant(vec->orientation->qz), "Quaternion part z"); + offerDataFieldWithDefault(tcpName,"qw", Variant(vec->orientation->qw), "Quaternion part w"); + offerDataFieldWithDefault(tcpName,"frame", Variant(vec->frame), "Reference Frame"); + } + else + { + setDataField(tcpName,"x", Variant(vec->position->x)); + setDataField(tcpName,"y", Variant(vec->position->y)); + setDataField(tcpName,"z", Variant(vec->position->z)); + setDataField(tcpName,"qx", Variant(vec->orientation->qx)); + setDataField(tcpName,"qy", Variant(vec->orientation->qy)); + setDataField(tcpName,"qz", Variant(vec->orientation->qz)); + setDataField(tcpName,"qw", Variant(vec->orientation->qw)); + setDataField(tcpName,"frame", Variant(vec->frame)); + } + + } + } + + void TCPControlUnitObserver::reportTCPVelocities(const FramedVector3Map &, const FramedVector3Map &, const Ice::Current &) + { + } + +} + + diff --git a/source/RobotAPI/units/TCPControlUnitObserver.h b/source/RobotAPI/units/TCPControlUnitObserver.h new file mode 100644 index 0000000000000000000000000000000000000000..727a9a17ac9300ad0afc94865ee4b952a58aa24a --- /dev/null +++ b/source/RobotAPI/units/TCPControlUnitObserver.h @@ -0,0 +1,69 @@ +/** +* This file is part of ArmarX. +* +* ArmarX is free software; you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as +* published by the Free Software Foundation; either version 2 of +* the License, or (at your option) any later version. +* +* 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 Lesser 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 2013 +* @copyright http://www.gnu.org/licenses/gpl.txt +* GNU General Public License +*/ +#ifndef _ARMARX_TCPCONTROLUNITOBSERVER_H +#define _ARMARX_TCPCONTROLUNITOBSERVER_H + +#include <Core/observers/Observer.h> +#include <RobotAPI/interface/units/TCPControlUnit.h> + +namespace armarx { + + class TCPControlUnitObserverPropertyDefinitions: + public ComponentPropertyDefinitions + { + public: + TCPControlUnitObserverPropertyDefinitions(std::string prefix): + ComponentPropertyDefinitions(prefix) + { + defineRequiredProperty<std::string>("TCPControlUnitName","Name of the TCPControlUnit"); + } + }; + + class TCPControlUnitObserver : + virtual public Observer, + virtual public TCPControlUnitObserverInterface + { + public: + TCPControlUnitObserver(); + + // framework hooks + virtual std::string getDefaultName() const { return "TCPControlUnitObserver"; } + void onInitObserver(); + void onConnectObserver(); + + /** + * @see PropertyUser::createPropertyDefinitions() + */ + virtual PropertyDefinitionsPtr createPropertyDefinitions(); + + // TCPControlUnitListener interface + public: + void reportTCPPose(const FramedPoseBaseMap &poseMap, const Ice::Current &); + void reportTCPVelocities(const FramedVector3Map &, const FramedVector3Map &, const Ice::Current &); + + Mutex dataMutex; + }; + +} + +#endif