MoveTCPToTarget.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @package RobotSkillTemplates::MotionControlGroup
17  * @author Mirko Waechter ( mirko dot waechter at kit dot edu )
18  * @date 2017
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 #include "MoveTCPToTarget.h"
24 
25 //#include <ArmarXCore/core/time/TimeUtil.h>
26 //#include <ArmarXCore/observers/variant/DatafieldRef.h>
28 
30 
31 using namespace armarx;
32 using namespace MotionControlGroup;
33 
34 // DO NOT EDIT NEXT LINE
35 MoveTCPToTarget::SubClassRegistry MoveTCPToTarget::Registry(MoveTCPToTarget::GetName(), &MoveTCPToTarget::CreateInstance);
36 
37 Eigen::Vector3f GetClosestPoint(const Eigen::Vector3f& p1, const Eigen::Vector3f& p2, const Eigen::Vector3f& p)
38 {
39  Eigen::Vector3f dir = p2 - p1;
40  return p1 - (p1 - p).dot(dir) * dir / dir.squaredNorm();
41 }
42 
43 float GetT(const Eigen::Vector3f& p1, const Eigen::Vector3f& p2, const Eigen::Vector3f& p)
44 {
45  Eigen::Vector3f dir = p2 - p1;
46  return (p - p1).dot(dir) / dir.squaredNorm();
47 }
48 
49 
50 Eigen::Vector3f Get(const Eigen::Vector3f& p1, const Eigen::Vector3f& p2, float t)
51 {
52  Eigen::Vector3f dir = p2 - p1;
53  return p1 + t * dir;
54 }
55 
56 
58 {
59  // put your user code for the enter-point here
60  // execution time should be short (<100ms)
61 }
62 
64 {
65  // put your user code for the execution-phase here
66  // runs in seperate thread, thus can do complex operations
67  // should check constantly whether isRunningTaskStopped() returns true
68  MotionControlGroupStatechartContext* c = getContext<MotionControlGroupStatechartContext>();
69  bool wasAlreadyRequested = c->getTCPControlUnit()->isRequested();
70  if (!wasAlreadyRequested)
71  {
72  c->getTCPControlUnit()->request();
73  }
74  std::string tcpName;
75  if (in.isTCPNameSet())
76  {
77  tcpName = in.getTCPName();
78  }
79  else
80  {
81  tcpName = c->getRobot()->getRobotNodeSet(in.getKinematicChainName())->getTCP()->getName();
82  }
83  std::string kinematicChainName = in.getKinematicChainName();
84  FramedPosePtr startPose = new FramedPose(c->getRobot()->getRobotNode(tcpName)->getPoseInRootFrame(), c->getRobot()->getRootNode()->getName(), c->getRobot()->getName());
85  FramedPosePtr targetPose = in.getTargetPose();
86  auto robot = c->getLocalRobot();
87 
88  FramedPosePtr globalTargetPose = targetPose->toGlobal(robot);
89 
90  Eigen::Vector3f startPositionInRootFrame = startPose->toEigen().block<3, 1>(0, 3);
91  Eigen::Vector3f targetPositionInRootFrame = targetPose->toRootEigen(c->getRobot()->clone()).block<3, 1>(0, 3);
92  // out.setStartPose(FramedPosePtr::dynamicCast(startPose->clone()));
93  auto sharedRobot = c->getRobotStateComponent()->getSynchronizedRobot();
94  auto tcp = robot->getRobotNode(tcpName);
95  float tcpVelocity = in.getTCPVelocity();
96  // Eigen::Vector3f tcpDirectionInRootFrame = in.getMoveDirection()->toRootEigen(robot).normalized();
97  // int sleepTimeMilliSec = int(1.0f / in.getControlFrequency() * 1000.0f);
98  // ARMARX_INFO << "Keeping orientation: " << keepOrientation;
99  // Eigen::Quaternionf deltaOri((startPose->toEigen().inverse() * in.getTargetPose()->toEigen()).block<3,3>(0,0));
100  Eigen::Quaternionf startOri(startPose->toEigen().block<3, 3>(0, 0));
101  Eigen::Quaternionf targetOri(in.getTargetPose()->toRootEigen(robot).block<3, 3>(0, 0));
102  float tOffset = in.getTOffset();
103  float ignoreOrientation = in.getIgnoreOrientationBeforeT();
104  armarx::CycleUtil cycle(1000.f / in.getControlFrequency());
105  auto toleratedAngleError = in.getToleratedOrientationDifference();
106 
107  float pOri = in.getKpOrientation();
108  // uncomment this if you need a continous run function. Make sure to use sleep or use blocking wait to reduce cpu load.
109  while (!isRunningTaskStopped()) // stop run function if returning true
110  {
111  RemoteRobot::synchronizeLocalClone(robot, sharedRobot);
112 
113  float t = GetT(startPositionInRootFrame, targetPositionInRootFrame, tcp->getPositionInRootFrame());
114  float tPos = t + tOffset;
115  Eigen::Quaternionf currentTargetOri = startOri.slerp(t, targetOri);
116 
117 
118  FramedDirectionPtr orientationVel, positionVel;
119 
120  Eigen::Vector3f orientationDelta;
121  FramedOrientationPtr TCPDeltaToCurrentTarget = new FramedOrientation(currentTargetOri.toRotationMatrix(), robot->getRootNode()->getName(), robot->getName());
122  TCPDeltaToCurrentTarget->changeFrame(robot, tcpName);
123  Eigen::Matrix4f orientationDelta4x4 = Eigen::Matrix4f::Identity();
124  orientationDelta4x4.block<3, 3>(0, 0) = TCPDeltaToCurrentTarget->toEigen();
125  VirtualRobot::MathTools::eigen4f2rpy(orientationDelta4x4, orientationDelta);
126  orientationVel = new FramedDirection(orientationDelta * pOri, tcpName, robot->getName());
127  orientationVel->changeFrame(robot, robot->getRootNode()->getName());
128  Eigen::Vector3f axis;
129  float angleError = 0;
130  orientationDelta4x4.block<3, 3>(0, 0) = TCPDeltaToCurrentTarget->toEigen();
131  VirtualRobot::MathTools::eigen4f2axisangle(orientationDelta4x4, axis, angleError);
132 
133 
134  Eigen::Vector3f currentTargetPosition = Get(startPositionInRootFrame, targetPositionInRootFrame, tPos);
135  float positionError = (currentTargetPosition - tcp->getPositionInRootFrame()).norm();
136  c->getDebugDrawerTopicProxy()->setPoseVisu("MoveTCPToTarget", "CurrentPose", new Pose(tcp->getGlobalPose()));
137  c->getDebugDrawerTopicProxy()->setPoseVisu("MoveTCPToTarget", "TargetPose", globalTargetPose);
138  c->getDebugDrawerTopicProxy()->setSphereVisu("MoveTCPToTarget", "CurrentTargetPose", FramedPosition(currentTargetPosition, robot->getRootNode()->getName(), robot->getName()).toGlobal(robot), DrawColor {1.0, 0, 0, 1}, 10);
139 
140  Eigen::Vector3f positionVelEigen = (currentTargetPosition - tcp->getPositionInRootFrame()).normalized() * tcpVelocity;
141  positionVel = new FramedDirection(positionVelEigen, robot->getRootNode()->getName(), robot->getName());
142 
143  if (t >= 1)
144  {
145  emitSuccess();
146  break;
147  }
148  ARMARX_INFO << deactivateSpam(1) << VAROUT(t) << VAROUT(positionError) << VAROUT(angleError) << VAROUT(positionVel->output());// << VAROUT(startPositionInRootFrame) << VAROUT(tcp->getPositionInRootFrame());
149  orientationVel = t < ignoreOrientation ? FramedDirectionPtr() : orientationVel;
150  if (angleError < toleratedAngleError)
151  {
152  orientationVel = nullptr;
153  }
154  c->getTCPControlUnit()->setTCPVelocity(kinematicChainName, tcpName, positionVel, orientationVel);
155  cycle.waitForCycleDuration();
156  }
157  c->getDebugDrawerTopicProxy()->clearLayer("MoveTCPToTarget");
158 
159  FramedDirectionPtr zeroVelocity(new FramedDirection(0, 0, 0, tcpName, robot->getName()));
160  c->getTCPControlUnit()->setTCPVelocity(kinematicChainName, tcpName, zeroVelocity, zeroVelocity);
161  TimeUtil::MSSleep(100);
162  if (!wasAlreadyRequested)
163  {
164  c->getTCPControlUnit()->release();
165  }
166 
167 }
168 
169 //void MoveTCPToTarget::onBreak()
170 //{
171 // // put your user code for the breaking point here
172 // // execution time should be short (<100ms)
173 //}
174 
176 {
177  // put your user code for the exit point here
178  // execution time should be short (<100ms)
179 }
180 
181 
182 // DO NOT EDIT NEXT FUNCTION
184 {
185  return XMLStateFactoryBasePtr(new MoveTCPToTarget(stateData));
186 }
187 
armarx::MotionControlGroup::MoveTCPToTarget::onExit
void onExit() override
Definition: MoveTCPToTarget.cpp:175
armarx::navigation::core::Pose
Eigen::Isometry3f Pose
Definition: basic_types.h:31
armarx::MotionControlGroup::MotionControlGroupStatechartContext
Definition: MotionControlGroupStatechartContext.h:66
armarx::RemoteRobot::synchronizeLocalClone
static bool synchronizeLocalClone(VirtualRobot::RobotPtr robot, RobotStateComponentInterfacePrx robotStatePrx)
Definition: RemoteRobot.cpp:448
armarx::VariantType::FramedPose
const VariantTypeId FramedPose
Definition: FramedPose.h:37
armarx::FramedDirectionPtr
IceInternal::Handle< FramedDirection > FramedDirectionPtr
Definition: FramedPose.h:81
armarx::TimeUtil::MSSleep
static void MSSleep(int durationMS)
lock the calling thread for a given duration (like usleep(...) but using Timeserver time)
Definition: TimeUtil.cpp:94
armarx::XMLStateConstructorParams
Definition: XMLState.h:50
armarx::MotionControlGroup::MoveTCPToTarget::MoveTCPToTarget
MoveTCPToTarget(const XMLStateConstructorParams &stateData)
Definition: MoveTCPToTarget.h:33
armarx::MotionControlGroup::MoveTCPToTarget::CreateInstance
static XMLStateFactoryBasePtr CreateInstance(XMLStateConstructorParams stateData)
Definition: MoveTCPToTarget.cpp:183
armarx::CycleUtil
This util class helps with keeping a cycle time during a control cycle.
Definition: CycleUtil.h:40
GetClosestPoint
Eigen::Vector3f GetClosestPoint(const Eigen::Vector3f &p1, const Eigen::Vector3f &p2, const Eigen::Vector3f &p)
Definition: MoveTCPToTarget.cpp:37
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
IceInternal::Handle< FramedPose >
armarx::Quaternion::slerp
Eigen::Matrix3f slerp(float, const Eigen::Matrix3f &)
Definition: Pose.cpp:233
deactivateSpam
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition: Logging.cpp:72
GetT
float GetT(const Eigen::Vector3f &p1, const Eigen::Vector3f &p2, const Eigen::Vector3f &p)
Definition: MoveTCPToTarget.cpp:43
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:523
Get
Eigen::Vector3f Get(const Eigen::Vector3f &p1, const Eigen::Vector3f &p2, float t)
Definition: MoveTCPToTarget.cpp:50
armarx::MotionControlGroup::MoveTCPToTarget::onEnter
void onEnter() override
Definition: MoveTCPToTarget.cpp:57
armarx::CycleUtil::waitForCycleDuration
IceUtil::Time waitForCycleDuration()
This function will wait (virtual or system time) until the cycle time is reached.
Definition: CycleUtil.cpp:53
MotionControlGroupStatechartContext.h
CycleUtil.h
armarx::XMLStateFactoryBasePtr
IceInternal::Handle< XMLStateFactoryBase > XMLStateFactoryBasePtr
Definition: XMLState.h:65
MoveTCPToTarget.h
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:601
armarx::MotionControlGroup::MoveTCPToTarget::Registry
static SubClassRegistry Registry
Definition: MoveTCPToTarget.h:46
armarx::VariantType::FramedOrientation
const VariantTypeId FramedOrientation
Definition: FramedPose.h:40
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::VariantType::FramedDirection
const VariantTypeId FramedDirection
Definition: FramedPose.h:38
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:182
armarx::Quaternion< float, 0 >
dot
double dot(const Point &x, const Point &y)
Definition: point.hpp:53
armarx::VariantType::FramedPosition
const VariantTypeId FramedPosition
Definition: FramedPose.h:39
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::MotionControlGroup::MoveTCPToTarget::run
void run() override
Definition: MoveTCPToTarget.cpp:63
norm
double norm(const Point &a)
Definition: point.hpp:94