diff --git a/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseObserver.cpp b/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseObserver.cpp index a29e434694593cdb0f87f4e524b1fbafbbc25cf3..760af325a522618218a7d39ceaf45d9fa20fa65a 100644 --- a/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseObserver.cpp +++ b/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseObserver.cpp @@ -30,6 +30,9 @@ #include <VirtualRobot/Robot.h> #include <VirtualRobot/RobotConfig.h> +#include <ArmarXCore/core/exceptions/local/UnexpectedEnumValueException.h> +#include <ArmarXCore/observers/variant/Variant.h> + #include <RobotAPI/libraries/core/Pose.h> #include <RobotAPI/libraries/core/FramedPose.h> #include <RobotAPI/libraries/ArmarXObjects/ice_conversions.h> @@ -49,6 +52,7 @@ namespace armarx defs->defineOptionalProperty<std::string>("ObjectPoseTopicName", "ObjectPoseTopic", "Name of the Object Pose Topic."); defs->defineOptionalProperty<std::string>("KinematicUnitObserverName", "KinematicUnitObserver", "Name of the kinematic unit observer."); + defs->topic(debugObserver); defs->optional(visu.enabled, "visu.enabled", "Enable or disable visualization of objects."); defs->optional(visu.inGlobalFrame, "visu.inGlobalFrame", "If true, show global poses. If false, show poses in robot frame."); @@ -56,9 +60,11 @@ namespace armarx defs->optional(visu.oobbs, "visu.oobbs", "Enable showing oriented bounding boxes."); defs->optional(visu.objectFrames, "visu.objectFrames", "Enable showing object frames."); defs->optional(visu.objectFramesScale, "visu.objectFramesScale", "Scaling of object frames."); + defs->optional(calibration.robotNode, "calibration.robotNode", "Robot node which can be calibrated."); defs->optional(calibration.offset, "calibration.offset", "Offset for the node to be calibrated."); - defs->optional(robotHead.checkHeadVelocity, "head.checkHeadVelocity", "If true, check whether the head is moving."); + + defs->optional(robotHead.checkHeadVelocity, "head.checkHeadVelocity", "If true, check whether the head is moving and discard updates in the meantime."); defs->optional(robotHead.maxJointVelocity, "head.maxJointVelocity", "If a head joint's velocity is higher, the head is considered moving."); defs->optional(robotHead.discardIntervalAfterMoveMS, "head.discardIntervalAfterMoveMS", "For how long new updates are ignored after moving the head."); @@ -72,6 +78,8 @@ namespace armarx void ObjectPoseObserver::onInitObserver() { + robotHead.setTag(getName()); + usingTopicFromProperty("ObjectPoseTopicName"); } @@ -85,6 +93,7 @@ namespace armarx } getProxyFromProperty(robotHead.kinematicUnitObserver, "KinematicUnitObserverName", false, "", false); + robotHead.debugObserver = debugObserver; robotHead.fetchDatafields(); createRemoteGuiTab(); @@ -100,62 +109,6 @@ namespace armarx } - void ObjectPoseObserver::createRemoteGuiTab() - { - using namespace armarx::RemoteGui::Client; - - tab.visuEnabled.setValue(visu.enabled); - tab.visuInGlobalFrame.setValue(visu.inGlobalFrame); - tab.visuAlpha.setRange(0, 1.0); - tab.visuAlpha.setValue(visu.alpha); - tab.visuOOBBs.setValue(visu.oobbs); - tab.visuObjectFrames.setValue(visu.objectFrames); - { - float max = 10000; - tab.visuObjectFramesScale.setRange(0, max); - tab.visuObjectFramesScale.setDecimals(2); - tab.visuObjectFramesScale.setSteps(int(10 * max)); - tab.visuObjectFramesScale.setValue(visu.objectFramesScale); - } - - GroupBox visuGroup; - { - GridLayout grid; - int row = 0; - grid.add(Label("Enabled"), {row, 0}).add(tab.visuEnabled, {row, 1}); - row++; - grid.add(Label("Global Frame"), {row, 0}).add(tab.visuInGlobalFrame, {row, 1}); - row++; - grid.add(Label("Alpha"), {row, 0}).add(tab.visuAlpha, {row, 1}, {1, 3}); - row++; - grid.add(Label("OOBB"), {row, 0}).add(tab.visuOOBBs, {row, 1}); - row++; - grid.add(Label("Object Frames"), {row, 0}).add(tab.visuObjectFrames, {row, 1}); - grid.add(Label("Scale:"), {row, 2}).add(tab.visuObjectFramesScale, {row, 3}); - row++; - - visuGroup.setLabel("Visualization"); - visuGroup.addChild(grid); - } - - VBoxLayout root = {visuGroup, VSpacer()}; - RemoteGui_createTab(getName(), root, &tab); - } - - void ObjectPoseObserver::RemoteGui_update() - { - // Non-atomic variables need to be guarded by a mutex if accessed by multiple threads - std::scoped_lock lock(dataMutex); - - visu.enabled = tab.visuEnabled.getValue(); - visu.inGlobalFrame = tab.visuInGlobalFrame.getValue(); - visu.alpha = tab.visuAlpha.getValue(); - visu.oobbs = tab.visuOOBBs.getValue(); - visu.objectFrames = tab.visuObjectFrames.getValue(); - visu.objectFramesScale = tab.visuObjectFramesScale.getValue(); - } - - void ObjectPoseObserver::reportProviderAvailable(const std::string& providerName, const objpose::ProviderInfo& info, const Ice::Current&) { updateProviderInfo(providerName, info); @@ -167,25 +120,45 @@ namespace armarx { ARMARX_VERBOSE << "Received object poses from '" << providerName << "'."; - IceUtil::Time discardUpdatesUntil; - if (robotHead.checkHeadVelocity) + std::optional<IceUtil::Time> discardUpdatesUntil; + bool discardAll = false; { std::scoped_lock lock(robotHeadMutex); - if (robotHead.isMoving()) + if (robotHead.checkHeadVelocity) { - robotHead.discardUpdatesUntil = TimeUtil::GetTime() + IceUtil::Time::milliSeconds(robotHead.discardIntervalAfterMoveMS); - // ARMARX_IMPORTANT << "Ignoring update because robot head is moving! until " << robotHead.discardUpdatesUntil; - return; + if (robotHead.isMoving()) + { + robotHead.movementStarts(robotHead.discardIntervalAfterMoveMS); + // ARMARX_IMPORTANT << "Ignoring pose update because robot head is moving! until " << robotHead.discardUpdatesUntil; + discardAll = true; + } + else if (TimeUtil::GetTime() < robotHead.discardUpdatesUntil) + { + discardAll = true; + // ARMARX_IMPORTANT << "Ignoring pose update because robot head has moved until: " << robotHead.discardUpdatesUntil; + } + else + { + discardUpdatesUntil = robotHead.discardUpdatesUntil; + } } - if (TimeUtil::GetTime() < robotHead.discardUpdatesUntil) + } + if (debugObserver) + { + StringVariantBaseMap map = { - // ARMARX_IMPORTANT << "Ignoring update because robot head is moved until: " << robotHead.discardUpdatesUntil; - return; + { "Discarding All Updates", new Variant(discardAll ? 1.f : 0.f) }, + }; + if (discardAll) + { + map["Proportion Updated Poses"] = new Variant(0.f); } - discardUpdatesUntil = robotHead.discardUpdatesUntil; + debugObserver->setDebugChannel(getName(), map); + } + if (discardAll) + { + return; } - - objpose::ObjectPoseSeq newObjectPoses; { std::scoped_lock lock(dataMutex); RobotState::synchronizeLocalClone(robot); @@ -204,10 +177,14 @@ namespace armarx previousPoses = it->second; } + // Build new poses. + objpose::ObjectPoseSeq newObjectPoses; + int numUpdated = 0; for (const objpose::data::ProvidedObjectPose& provided : providedPoses) { IceUtil::Time timestamp = IceUtil::Time::microSeconds(provided.timestampMicroSeconds); + // Check whether we have an old pose for this object. std::optional<objpose::ObjectPose> previousPose; for (const objpose::ObjectPose& prev : previousPoses) { @@ -217,7 +194,7 @@ namespace armarx } } - if (robotHead.checkHeadVelocity && timestamp < discardUpdatesUntil) + if (discardUpdatesUntil && timestamp < *discardUpdatesUntil) { if (previousPose) { @@ -238,6 +215,7 @@ namespace armarx } else { + numUpdated++; objpose::ObjectPose& newPose = newObjectPoses.emplace_back(); newPose.fromProvidedPose(provided, robot); if (newPose.objectID.dataset().empty()) @@ -250,14 +228,21 @@ namespace armarx } if (!provided.localOOBB) { + // Try to load oobb from disk. newPose.localOOBB = getObjectOOBB(newPose.objectID); } } } - } - { - std::scoped_lock lock(dataMutex); + if (debugObserver) + { + debugObserver->setDebugChannel(getName(), + { + { "Discarding All Updates", new Variant(discardAll ? 1 : 0) }, + { "Proportion Updated Poses", new Variant(static_cast<float>(numUpdated) / providedPoses.size()) } + }); + } + this->objectPoses[providerName] = newObjectPoses; handleProviderUpdate(providerName); } @@ -619,6 +604,28 @@ namespace armarx return output; } + objpose::SignalHeadMovementOutput + ObjectPoseObserver::signalHeadMovement(const objpose::SignalHeadMovementInput& input, const Ice::Current&) + { + std::scoped_lock lock(robotHeadMutex); + objpose::SignalHeadMovementOutput output; + switch (input.action) + { + case objpose::HeadMovementAction::HeadMovementAction_Starting: + robotHead.movementStarts(input.discardUpdatesIntervalMilliSeconds < 0 + ? robotHead.discardIntervalAfterMoveMS + : input.discardUpdatesIntervalMilliSeconds); + break; + case objpose::HeadMovementAction::HeadMovementAction_Stopping: + robotHead.movementStops(input.discardUpdatesIntervalMilliSeconds); + break; + default: + ARMARX_UNEXPECTED_ENUM_VALUE(objpose::HeadMovementaction, input.action); + break; + } + output.discardUpdatesUntilMilliSeconds = robotHead.discardUpdatesUntil.toMilliSeconds(); + return output; + } void ObjectPoseObserver::handleProviderUpdate(const std::string& providerName) @@ -826,7 +833,7 @@ namespace armarx } } - void ObjectPoseObserver::RobotHead::fetchDatafields() + void ObjectPoseObserver::RobotHeadMovement::fetchDatafields() { if (kinematicUnitObserver) { @@ -852,21 +859,25 @@ namespace armarx } if (error.size() > 0) { - ARMARX_WARNING_S << "Could not get datafield for joint '" << jointName << "' in channel '" << jointVelocitiesChannelName << "': \n " - << error; + ARMARX_WARNING << "Could not get datafield for joint '" << jointName << "' in channel '" << jointVelocitiesChannelName << "': \n " + << error; } } } + else + { + ARMARX_INFO << "Cannot fetch joint velocity datafields because there is no kinematic unit observer."; + } } - bool ObjectPoseObserver::RobotHead::isMoving() const + bool ObjectPoseObserver::RobotHeadMovement::isMoving() const { for (DatafieldRefPtr df : jointVelocitiesDatafields) { if (df) { float jointVelocity = df->getFloat(); - // ARMARX_IMPORTANT_S << "Is " << df->datafieldName << " " << VAROUT(std::abs(jointVelocity)) << " > " << VAROUT(maxJointVelocity) << "?"; + // ARMARX_IMPORTANT << "Is " << df->datafieldName << " " << VAROUT(std::abs(jointVelocity)) << " > " << VAROUT(maxJointVelocity) << "?"; if (std::abs(jointVelocity) > maxJointVelocity) { return true; @@ -876,5 +887,123 @@ namespace armarx return false; } + void ObjectPoseObserver::RobotHeadMovement::movementStarts(long discardIntervalMs) + { + return movementStarts(IceUtil::Time::milliSeconds(discardIntervalMs)); + } + void ObjectPoseObserver::RobotHeadMovement::movementStarts(IceUtil::Time discardInterval) + { + discardUpdatesUntil = TimeUtil::GetTime() + discardInterval; + } + void ObjectPoseObserver::RobotHeadMovement::movementStops(long discardIntervalMs) + { + return movementStops(IceUtil::Time::milliSeconds(discardIntervalMs)); + } + void ObjectPoseObserver::RobotHeadMovement::movementStops(IceUtil::Time discardInterval) + { + if (discardInterval.toMilliSeconds() < 0) + { + // Stop discarding. + discardUpdatesUntil = IceUtil::Time::milliSeconds(-1); + } + else + { + // Basically the same as starting. + discardUpdatesUntil = TimeUtil::GetTime() + discardInterval; + } + } + + + void ObjectPoseObserver::createRemoteGuiTab() + { + using namespace armarx::RemoteGui::Client; + + GroupBox visuGroup; + { + tab.visu.enabled.setValue(visu.enabled); + tab.visu.inGlobalFrame.setValue(visu.inGlobalFrame); + tab.visu.alpha.setRange(0, 1.0); + tab.visu.alpha.setValue(visu.alpha); + tab.visu.oobbs.setValue(visu.oobbs); + tab.visu.objectFrames.setValue(visu.objectFrames); + { + float max = 10000; + tab.visu.objectFramesScale.setRange(0, max); + tab.visu.objectFramesScale.setDecimals(2); + tab.visu.objectFramesScale.setSteps(int(10 * max)); + tab.visu.objectFramesScale.setValue(visu.objectFramesScale); + } + + GridLayout grid; + int row = 0; + grid.add(Label("Enabled"), {row, 0}).add(tab.visu.enabled, {row, 1}); + row++; + grid.add(Label("Global Frame"), {row, 0}).add(tab.visu.inGlobalFrame, {row, 1}); + row++; + grid.add(Label("Alpha"), {row, 0}).add(tab.visu.alpha, {row, 1}, {1, 3}); + row++; + grid.add(Label("OOBB"), {row, 0}).add(tab.visu.oobbs, {row, 1}); + row++; + grid.add(Label("Object Frames"), {row, 0}).add(tab.visu.objectFrames, {row, 1}); + grid.add(Label("Scale:"), {row, 2}).add(tab.visu.objectFramesScale, {row, 3}); + row++; + + visuGroup.setLabel("Visualization"); + visuGroup.addChild(grid); + } + + GroupBox robotHeadGroup; + { + tab.robotHead.checkHeadVelocity.setValue(robotHead.checkHeadVelocity); + { + float max = 10.0; + tab.robotHead.maxJointVelocity.setRange(0, max); + tab.robotHead.maxJointVelocity.setDecimals(3); + tab.robotHead.maxJointVelocity.setSteps(int(100 * max)); // = 0.01 steps + tab.robotHead.maxJointVelocity.setValue(robotHead.maxJointVelocity); + } + { + int max = 10 * 1000; + tab.robotHead.discardIntervalAfterMoveMS.setRange(0, max); + tab.robotHead.discardIntervalAfterMoveMS.setValue(robotHead.discardIntervalAfterMoveMS); + } + + GridLayout grid; + int row = 0; + grid.add(Label("Check Head Motion"), {row, 0}).add(tab.robotHead.checkHeadVelocity, {row, 1}); + row++; + grid.add(Label("Max Joint Velocity"), {row, 0}).add(tab.robotHead.maxJointVelocity, {row, 1}); + row++; + grid.add(Label("Discard Interval after Move [ms]"), {row, 0}).add(tab.robotHead.discardIntervalAfterMoveMS, {row, 1}); + row++; + + robotHeadGroup.setLabel("Robot Head Motion"); + robotHeadGroup.addChild(grid); + } + + VBoxLayout root = {visuGroup, robotHeadGroup, VSpacer()}; + RemoteGui_createTab(getName(), root, &tab); + } + + void ObjectPoseObserver::RemoteGui_update() + { + // Non-atomic variables need to be guarded by a mutex if accessed by multiple threads + { + std::scoped_lock lock(dataMutex); + + visu.enabled = tab.visu.enabled.getValue(); + visu.inGlobalFrame = tab.visu.inGlobalFrame.getValue(); + visu.alpha = tab.visu.alpha.getValue(); + visu.oobbs = tab.visu.oobbs.getValue(); + visu.objectFrames = tab.visu.objectFrames.getValue(); + visu.objectFramesScale = tab.visu.objectFramesScale.getValue(); + } + { + std::scoped_lock lock(robotHeadMutex); + robotHead.checkHeadVelocity = tab.robotHead.checkHeadVelocity.getValue(); + robotHead.maxJointVelocity = tab.robotHead.maxJointVelocity.getValue(); + robotHead.discardIntervalAfterMoveMS = tab.robotHead.discardIntervalAfterMoveMS.getValue(); + } + } } diff --git a/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseObserver.h b/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseObserver.h index 1d5809452645dd1b7952a87ced9d8d05898fc44d..5022afbf2c92b7cba7a7c2455dbe26d0e3c1f88f 100644 --- a/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseObserver.h +++ b/source/RobotAPI/components/ObjectPoseObserver/ObjectPoseObserver.h @@ -26,6 +26,7 @@ #include <SimoxUtility/caching/CacheMap.h> +#include <ArmarXCore/core/logging/Logging.h> #include <ArmarXCore/observers/Observer.h> #include <ArmarXCore/observers/variant/DatafieldRef.h> @@ -74,7 +75,6 @@ namespace armarx , virtual public armarx::RobotStateComponentPluginUser , virtual public armarx::LightweightRemoteGuiComponentPluginUser , virtual public armarx::ArVizComponentPluginUser - { public: using RobotState = armarx::RobotStateComponentPluginUser; @@ -116,6 +116,11 @@ namespace armarx objpose::AgentFramesSeq getAttachableFrames(ICE_CURRENT_ARG) override; + // HEAD MOVEMENT SIGNALS + + objpose::SignalHeadMovementOutput signalHeadMovement(const objpose::SignalHeadMovementInput& input, ICE_CURRENT_ARG) override; + + // Remote GUI void createRemoteGuiTab(); @@ -124,13 +129,14 @@ namespace armarx protected: + armarx::PropertyDefinitionsPtr createPropertyDefinitions() override; + void onInitObserver() override; void onConnectObserver() override; void onDisconnectComponent() override; void onExitObserver() override; - armarx::PropertyDefinitionsPtr createPropertyDefinitions() override; private: @@ -153,45 +159,55 @@ namespace armarx void toIceWithAttachments(objpose::ObjectPoseSeq& objectPoses, VirtualRobot::RobotPtr agent, objpose::data::ObjectPoseSeq& result, bool& synchronized); - private: std::mutex dataMutex; VirtualRobot::RobotPtr robot; + DebugObserverInterfacePrx debugObserver; + + + objpose::ProviderInfoMap providers; + + std::map<std::string, objpose::ObjectPoseSeq> objectPoses; + std::map<std::string, int> updateCounters; + + std::map<std::pair<std::string, ObjectID>, objpose::ObjectAttachmentInfo> attachments; + + + ObjectFinder objectFinder; + /// Caches results of attempts to retrieve the OOBB from ArmarXObjects. + simox::caching::CacheMap<ObjectID, std::optional<simox::OrientedBoxf>> oobbCache; + - struct RobotHead + class RobotHeadMovement : public armarx::Logging { + public: + bool checkHeadVelocity = true; std::string jointVelocitiesChannelName = "jointvelocities"; std::vector<std::string> jointNames = {"Neck_1_Yaw", "Neck_2_Pitch"}; - float maxJointVelocity = 0.05; + float maxJointVelocity = 0.05f; int discardIntervalAfterMoveMS = 100; KinematicUnitObserverInterfacePrx kinematicUnitObserver; std::vector<DatafieldRefPtr> jointVelocitiesDatafields; IceUtil::Time discardUpdatesUntil = IceUtil::Time::seconds(-1); + DebugObserverInterfacePrx debugObserver; + void fetchDatafields(); bool isMoving() const; + + void movementStarts(long discardIntervalMs); + void movementStarts(IceUtil::Time discardInterval); + void movementStops(long discardIntervalMs); + void movementStops(IceUtil::Time discardInterval); }; - RobotHead robotHead; + RobotHeadMovement robotHead; std::mutex robotHeadMutex; - - objpose::ProviderInfoMap providers; - - std::map<std::string, objpose::ObjectPoseSeq> objectPoses; - std::map<std::string, int> updateCounters; - - std::map<std::pair<std::string, ObjectID>, objpose::ObjectAttachmentInfo> attachments; - - - ObjectFinder objectFinder; - /// Caches results of attempts to retrieve the OOBB from ArmarXObjects. - simox::caching::CacheMap<ObjectID, std::optional<simox::OrientedBoxf>> oobbCache; - struct Visu { bool enabled = false; @@ -211,16 +227,26 @@ namespace armarx Calibration calibration; - - struct RemoteGuiTab : RemoteGui::Client::Tab { - RemoteGui::Client::CheckBox visuEnabled; - RemoteGui::Client::CheckBox visuInGlobalFrame; - RemoteGui::Client::FloatSlider visuAlpha; - RemoteGui::Client::CheckBox visuOOBBs; - RemoteGui::Client::CheckBox visuObjectFrames; - RemoteGui::Client::FloatSpinBox visuObjectFramesScale; + struct Visu + { + RemoteGui::Client::CheckBox enabled; + RemoteGui::Client::CheckBox inGlobalFrame; + RemoteGui::Client::FloatSlider alpha; + RemoteGui::Client::CheckBox oobbs; + RemoteGui::Client::CheckBox objectFrames; + RemoteGui::Client::FloatSpinBox objectFramesScale; + }; + Visu visu; + + struct RobotHead + { + RemoteGui::Client::CheckBox checkHeadVelocity; + RemoteGui::Client::FloatSpinBox maxJointVelocity; + RemoteGui::Client::IntSpinBox discardIntervalAfterMoveMS; + }; + RobotHead robotHead; }; RemoteGuiTab tab; diff --git a/source/RobotAPI/interface/objectpose/ObjectPoseObserver.ice b/source/RobotAPI/interface/objectpose/ObjectPoseObserver.ice index 602043ab3b17e3afbdfbbd87b835dda80f264f29..850647b279975f4f79adfb95d89b46c10ebb5c8e 100644 --- a/source/RobotAPI/interface/objectpose/ObjectPoseObserver.ice +++ b/source/RobotAPI/interface/objectpose/ObjectPoseObserver.ice @@ -104,6 +104,35 @@ module armarx }; sequence<AgentFrames> AgentFramesSeq; + + enum HeadMovementAction + { + /// Head movement is about to start. + HeadMovementAction_Starting, + /// Head movement is stopping. + HeadMovementAction_Stopping + }; + struct SignalHeadMovementInput + { + HeadMovementAction action; + + /** + * If starting, for how long (after this call) new poses shall be discarded + * due to head movement. + * When set to -1 (default), the configured value in the component is used. + * + * If stopping, for how long (after this call) new poses shall be discarded + * due to remaining head movement. + * When set to -1 (default), resume processing updates immediately. + */ + long discardUpdatesIntervalMilliSeconds = -1; + }; + struct SignalHeadMovementOutput + { + /// The time until new updates will be discarded. + long discardUpdatesUntilMilliSeconds = -1; + }; + interface ObjectPoseObserverInterface extends ObserverInterface, ObjectPoseTopic { // Object poses @@ -133,6 +162,15 @@ module armarx AgentFramesSeq getAttachableFrames(); + + /* + * Notifying about head/camera movement. + * While the head is moving (and a short time afterwards), pose updates are discarded + * as they can be bad due to camera movement. + */ + + SignalHeadMovementOutput signalHeadMovement(SignalHeadMovementInput input); + }; }; diff --git a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateHelper.cpp b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateHelper.cpp index 3533eb02cc11c3598813f330e202e9b673155136..c4f221549de4e12a04e1a495e7a8448fa9c64b3e 100644 --- a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateHelper.cpp +++ b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateHelper.cpp @@ -38,8 +38,7 @@ GraspCandidateHelper::GraspCandidateHelper(const grasping::GraspCandidatePtr& ca Eigen::Matrix4f GraspCandidateHelper::getGraspPoseInRobotRoot() const { - const Eigen::Matrix4f curRobotPose = robot->getGlobalPose(); - const Eigen::Matrix4f graspPose = curRobotPose.inverse() * getGraspPoseInGlobal(); + const Eigen::Matrix4f graspPose = getFramedPose().toRootEigen(robot); return graspPose; } @@ -58,11 +57,18 @@ Eigen::Vector3f GraspCandidateHelper::getGraspPositionInRobotRoot() const return math::Helpers::GetPosition(getGraspPoseInRobotRoot()); } +armarx::FramedPose GraspCandidateHelper::getFramedPose() const +{ + return armarx::FramedPose(candidate->graspPose->position, + candidate->graspPose->orientation, + candidate->sourceFrame, + robot->getName()); +} + Eigen::Matrix4f GraspCandidateHelper::getGraspPoseInGlobal() const { - const Eigen::Matrix4f oldGraspPose = defrost(candidate->graspPose); - const Eigen::Matrix4f oldRobotPose = defrost(candidate->robotPose); - return oldRobotPose * oldGraspPose; + auto grasp_pose = getFramedPose(); + return grasp_pose.toGlobalEigen(robot); } Eigen::Matrix3f GraspCandidateHelper::getGraspOrientationInGlobal() const { diff --git a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateHelper.h b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateHelper.h index 050958f91cb13e5ad34f1a87110e759bc5402b1e..6c9ba617bc511278c77bc147eabb2ac18abc3b19 100644 --- a/source/RobotAPI/libraries/GraspingUtility/GraspCandidateHelper.h +++ b/source/RobotAPI/libraries/GraspingUtility/GraspCandidateHelper.h @@ -30,6 +30,7 @@ #include <VirtualRobot/Robot.h> #include <RobotAPI/libraries/core/Pose.h> +#include <RobotAPI/libraries/core/FramedPose.h> namespace armarx { @@ -50,6 +51,7 @@ namespace armarx Eigen::Matrix3f getGraspOrientationInRobotRoot() const; Eigen::Vector3f getGraspPositionInRobotRoot() const; + armarx::FramedPose getFramedPose() const; Eigen::Matrix4f getGraspPoseInGlobal() const; Eigen::Matrix3f getGraspOrientationInGlobal() const; Eigen::Vector3f getGraspPositionInGlobal() const; diff --git a/source/RobotAPI/libraries/RobotStatechartHelpers/VelocityControllerHelper.cpp b/source/RobotAPI/libraries/RobotStatechartHelpers/VelocityControllerHelper.cpp index d4d9a88466d407b83d72d9a5db48f2cade93aa42..456671e79cc764fc577121082967fcc52e341361 100644 --- a/source/RobotAPI/libraries/RobotStatechartHelpers/VelocityControllerHelper.cpp +++ b/source/RobotAPI/libraries/RobotStatechartHelpers/VelocityControllerHelper.cpp @@ -50,7 +50,7 @@ namespace armarx } else { - ctrl = robotUnit->createNJointController("NJointCartesianVelocityControllerWithRamp", controllerName, config); + ctrl = robotUnit->createOrReplaceNJointController("NJointCartesianVelocityControllerWithRamp", controllerName, config); controllerCreated = true; } controller = NJointCartesianVelocityControllerWithRampInterfacePrx::checkedCast(ctrl);