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 #include <VirtualRobot/MathTools.h>
25 #include <VirtualRobot/RobotNodeSet.h>
26 
27 //#include <ArmarXCore/core/time/TimeUtil.h>
28 //#include <ArmarXCore/observers/variant/DatafieldRef.h>
30 
32 
33 using namespace armarx;
34 using namespace MotionControlGroup;
35 
36 // DO NOT EDIT NEXT LINE
37 MoveTCPToTarget::SubClassRegistry MoveTCPToTarget::Registry(MoveTCPToTarget::GetName(),
39 
40 Eigen::Vector3f
41 GetClosestPoint(const Eigen::Vector3f& p1, const Eigen::Vector3f& p2, const Eigen::Vector3f& p)
42 {
43  Eigen::Vector3f dir = p2 - p1;
44  return p1 - (p1 - p).dot(dir) * dir / dir.squaredNorm();
45 }
46 
47 float
48 GetT(const Eigen::Vector3f& p1, const Eigen::Vector3f& p2, const Eigen::Vector3f& p)
49 {
50  Eigen::Vector3f dir = p2 - p1;
51  return (p - p1).dot(dir) / dir.squaredNorm();
52 }
53 
54 Eigen::Vector3f
55 Get(const Eigen::Vector3f& p1, const Eigen::Vector3f& p2, float t)
56 {
57  Eigen::Vector3f dir = p2 - p1;
58  return p1 + t * dir;
59 }
60 
61 void
63 {
64  // put your user code for the enter-point here
65  // execution time should be short (<100ms)
66 }
67 
68 void
70 {
71  // put your user code for the execution-phase here
72  // runs in seperate thread, thus can do complex operations
73  // should check constantly whether isRunningTaskStopped() returns true
74  MotionControlGroupStatechartContext* c = getContext<MotionControlGroupStatechartContext>();
75  bool wasAlreadyRequested = c->getTCPControlUnit()->isRequested();
76  if (!wasAlreadyRequested)
77  {
78  c->getTCPControlUnit()->request();
79  }
80  std::string tcpName;
81  if (in.isTCPNameSet())
82  {
83  tcpName = in.getTCPName();
84  }
85  else
86  {
87  tcpName = c->getRobot()->getRobotNodeSet(in.getKinematicChainName())->getTCP()->getName();
88  }
89  std::string kinematicChainName = in.getKinematicChainName();
90  FramedPosePtr startPose =
91  new FramedPose(c->getRobot()->getRobotNode(tcpName)->getPoseInRootFrame(),
92  c->getRobot()->getRootNode()->getName(),
93  c->getRobot()->getName());
94  FramedPosePtr targetPose = in.getTargetPose();
95  auto robot = c->getLocalRobot();
96 
97  FramedPosePtr globalTargetPose = targetPose->toGlobal(robot);
98 
99  Eigen::Vector3f startPositionInRootFrame = startPose->toEigen().block<3, 1>(0, 3);
100  Eigen::Vector3f targetPositionInRootFrame =
101  targetPose->toRootEigen(c->getRobot()->clone()).block<3, 1>(0, 3);
102  // out.setStartPose(FramedPosePtr::dynamicCast(startPose->clone()));
103  auto sharedRobot = c->getRobotStateComponent()->getSynchronizedRobot();
104  auto tcp = robot->getRobotNode(tcpName);
105  float tcpVelocity = in.getTCPVelocity();
106  // Eigen::Vector3f tcpDirectionInRootFrame = in.getMoveDirection()->toRootEigen(robot).normalized();
107  // int sleepTimeMilliSec = int(1.0f / in.getControlFrequency() * 1000.0f);
108  // ARMARX_INFO << "Keeping orientation: " << keepOrientation;
109  // Eigen::Quaternionf deltaOri((startPose->toEigen().inverse() * in.getTargetPose()->toEigen()).block<3,3>(0,0));
110  Eigen::Quaternionf startOri(startPose->toEigen().block<3, 3>(0, 0));
111  Eigen::Quaternionf targetOri(in.getTargetPose()->toRootEigen(robot).block<3, 3>(0, 0));
112  float tOffset = in.getTOffset();
113  float ignoreOrientation = in.getIgnoreOrientationBeforeT();
114  armarx::CycleUtil cycle(1000.f / in.getControlFrequency());
115  auto toleratedAngleError = in.getToleratedOrientationDifference();
116 
117  float pOri = in.getKpOrientation();
118  // uncomment this if you need a continous run function. Make sure to use sleep or use blocking wait to reduce cpu load.
119  while (!isRunningTaskStopped()) // stop run function if returning true
120  {
121  RemoteRobot::synchronizeLocalClone(robot, sharedRobot);
122 
123  float t = GetT(
124  startPositionInRootFrame, targetPositionInRootFrame, tcp->getPositionInRootFrame());
125  float tPos = t + tOffset;
126  Eigen::Quaternionf currentTargetOri = startOri.slerp(t, targetOri);
127 
128 
129  FramedDirectionPtr orientationVel, positionVel;
130 
131  Eigen::Vector3f orientationDelta;
132  FramedOrientationPtr TCPDeltaToCurrentTarget = new FramedOrientation(
133  currentTargetOri.toRotationMatrix(), robot->getRootNode()->getName(), robot->getName());
134  TCPDeltaToCurrentTarget->changeFrame(robot, tcpName);
135  Eigen::Matrix4f orientationDelta4x4 = Eigen::Matrix4f::Identity();
136  orientationDelta4x4.block<3, 3>(0, 0) = TCPDeltaToCurrentTarget->toEigen();
137  VirtualRobot::MathTools::eigen4f2rpy(orientationDelta4x4, orientationDelta);
138  orientationVel = new FramedDirection(orientationDelta * pOri, tcpName, robot->getName());
139  orientationVel->changeFrame(robot, robot->getRootNode()->getName());
140  Eigen::Vector3f axis;
141  float angleError = 0;
142  orientationDelta4x4.block<3, 3>(0, 0) = TCPDeltaToCurrentTarget->toEigen();
143  VirtualRobot::MathTools::eigen4f2axisangle(orientationDelta4x4, axis, angleError);
144 
145 
146  Eigen::Vector3f currentTargetPosition =
147  Get(startPositionInRootFrame, targetPositionInRootFrame, tPos);
148  float positionError = (currentTargetPosition - tcp->getPositionInRootFrame()).norm();
149  c->getDebugDrawerTopicProxy()->setPoseVisu(
150  "MoveTCPToTarget", "CurrentPose", new Pose(tcp->getGlobalPose()));
151  c->getDebugDrawerTopicProxy()->setPoseVisu(
152  "MoveTCPToTarget", "TargetPose", globalTargetPose);
153  c->getDebugDrawerTopicProxy()->setSphereVisu(
154  "MoveTCPToTarget",
155  "CurrentTargetPose",
156  FramedPosition(currentTargetPosition, robot->getRootNode()->getName(), robot->getName())
157  .toGlobal(robot),
158  DrawColor{1.0, 0, 0, 1},
159  10);
160 
161  Eigen::Vector3f positionVelEigen =
162  (currentTargetPosition - tcp->getPositionInRootFrame()).normalized() * tcpVelocity;
163  positionVel = new FramedDirection(
164  positionVelEigen, robot->getRootNode()->getName(), robot->getName());
165 
166  if (t >= 1)
167  {
168  emitSuccess();
169  break;
170  }
172  << deactivateSpam(1) << VAROUT(t) << VAROUT(positionError) << VAROUT(angleError)
173  << VAROUT(
174  positionVel
175  ->output()); // << VAROUT(startPositionInRootFrame) << VAROUT(tcp->getPositionInRootFrame());
176  orientationVel = t < ignoreOrientation ? FramedDirectionPtr() : orientationVel;
177  if (angleError < toleratedAngleError)
178  {
179  orientationVel = nullptr;
180  }
181  c->getTCPControlUnit()->setTCPVelocity(
182  kinematicChainName, tcpName, positionVel, orientationVel);
183  cycle.waitForCycleDuration();
184  }
185  c->getDebugDrawerTopicProxy()->clearLayer("MoveTCPToTarget");
186 
187  FramedDirectionPtr zeroVelocity(new FramedDirection(0, 0, 0, tcpName, robot->getName()));
188  c->getTCPControlUnit()->setTCPVelocity(kinematicChainName, tcpName, zeroVelocity, zeroVelocity);
189  TimeUtil::MSSleep(100);
190  if (!wasAlreadyRequested)
191  {
192  c->getTCPControlUnit()->release();
193  }
194 }
195 
196 //void MoveTCPToTarget::onBreak()
197 //{
198 // // put your user code for the breaking point here
199 // // execution time should be short (<100ms)
200 //}
201 
202 void
204 {
205  // put your user code for the exit point here
206  // execution time should be short (<100ms)
207 }
208 
209 // DO NOT EDIT NEXT FUNCTION
212 {
213  return XMLStateFactoryBasePtr(new MoveTCPToTarget(stateData));
214 }
armarx::MotionControlGroup::MoveTCPToTarget::onExit
void onExit() override
Definition: MoveTCPToTarget.cpp:203
armarx::navigation::core::Pose
Eigen::Isometry3f Pose
Definition: basic_types.h:31
armarx::MotionControlGroup::MotionControlGroupStatechartContext
Definition: MotionControlGroupStatechartContext.h:75
armarx::RemoteRobot::synchronizeLocalClone
static bool synchronizeLocalClone(VirtualRobot::RobotPtr robot, RobotStateComponentInterfacePrx robotStatePrx)
Definition: RemoteRobot.cpp:522
armarx::VariantType::FramedPose
const VariantTypeId FramedPose
Definition: FramedPose.h:36
armarx::FramedDirectionPtr
IceInternal::Handle< FramedDirection > FramedDirectionPtr
Definition: FramedPose.h:84
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:650
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:100
armarx::XMLStateConstructorParams
Definition: XMLState.h:49
armarx::MotionControlGroup::MoveTCPToTarget::MoveTCPToTarget
MoveTCPToTarget(const XMLStateConstructorParams &stateData)
Definition: MoveTCPToTarget.h:32
armarx::MotionControlGroup::MoveTCPToTarget::CreateInstance
static XMLStateFactoryBasePtr CreateInstance(XMLStateConstructorParams stateData)
Definition: MoveTCPToTarget.cpp:211
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:41
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
armarx::XMLStateFactoryBasePtr
IceInternal::Handle< XMLStateFactoryBase > XMLStateFactoryBasePtr
Definition: XMLState.h:64
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:75
GetT
float GetT(const Eigen::Vector3f &p1, const Eigen::Vector3f &p2, const Eigen::Vector3f &p)
Definition: MoveTCPToTarget.cpp:48
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:570
Get
Eigen::Vector3f Get(const Eigen::Vector3f &p1, const Eigen::Vector3f &p2, float t)
Definition: MoveTCPToTarget.cpp:55
armarx::MotionControlGroup::MoveTCPToTarget::onEnter
void onEnter() override
Definition: MoveTCPToTarget.cpp:62
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
MoveTCPToTarget.h
armarx::MotionControlGroup::MoveTCPToTarget::Registry
static SubClassRegistry Registry
Definition: MoveTCPToTarget.h:46
armarx::VariantType::FramedOrientation
const VariantTypeId FramedOrientation
Definition: FramedPose.h:39
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::VariantType::FramedDirection
const VariantTypeId FramedDirection
Definition: FramedPose.h:37
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:198
armarx::Quaternion< float, 0 >
dot
double dot(const Point &x, const Point &y)
Definition: point.hpp:57
armarx::VariantType::FramedPosition
const VariantTypeId FramedPosition
Definition: FramedPose.h:38
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::MotionControlGroup::MoveTCPToTarget::run
void run() override
Definition: MoveTCPToTarget.cpp:69
norm
double norm(const Point &a)
Definition: point.hpp:102