MoveTCPToTargetPose.cpp
Go to the documentation of this file.
1#include <SimoxUtility/algorithm/string/string_tools.h>
3
4#include <VirtualRobot/MathTools.h>
5
7
8namespace armarx::skills
9{
10 namespace
11 {
12 tcp_control::arondto::MoveTCPToTargetPoseAcceptedType
13 GetDefaultParameterization()
14 {
15 tcp_control::arondto::MoveTCPToTargetPoseAcceptedType ret;
16 ret.orientationalAccuracy = 0.01;
17 ret.positionalAccuracy = 25;
18 return ret;
19 }
20 } // namespace
21
22 SkillDescription MoveTCPToTargetPose::Description = skills::SkillDescription{
23 .skillId = {.skillName = "MoveTCPToTargetPose"},
24 .description = "Move the TCP to a target pose",
25 .rootProfileDefaults = GetDefaultParameterization().toAron(),
26 .timeout = armarx::Duration::MilliSeconds(15000),
27 .parametersType = tcp_control::arondto::MoveTCPToTargetPoseAcceptedType::ToAronType(),
28 };
29
40
42 MoveTCPToTargetPose::init(const SpecializedInitInput& in)
43 {
45
46 tcpControlUnitRequestedOnStart = true;
47 if (!context.tcpControlUnitPrx->isRequested())
48 {
49 tcpControlUnitRequestedOnStart = false;
50 context.tcpControlUnitPrx->request();
51 }
52 context.tcpControlUnitPrx->setCycleTime(100);
53
54 return {.status = TerminatedSkillStatus::Succeeded};
55 }
56
58 MoveTCPToTargetPose::step(const SpecializedMainInput& in)
59 {
60 auto robot =
61 robotReader.getSynchronizedRobot(in.parameters.robotName,
63 VirtualRobot::RobotIO::RobotDescription::eStructure);
64 if (!robot)
65 {
66 ARMARX_WARNING << "Unable to get robot from robotstatememory. Abort.";
68 }
69
70 std::string handRootNodeName = "Hand L Base";
71 std::string robotAPIHandFileName = "RobotAPI/robots/Armar3/ArmarIII-LeftHand.xml";
72 if (simox::alg::starts_with(in.parameters.kinematicChainName, "Right"))
73 {
74 handRootNodeName = "Hand R Base";
75 robotAPIHandFileName = "RobotAPI/robots/Armar3/ArmarIII-RightHand.xml";
76 }
77
78 std::string tcpName =
79 robot->getRobotNodeSet(in.parameters.kinematicChainName)->getTCP()->getName();
80
81 const Eigen::Matrix4f tcpPoseGlobal = robot->getRobotNode(tcpName)->getGlobalPose();
82 const Eigen::Matrix4f handRootPoseGlobal =
83 robot->getRobotNode(handRootNodeName)->getGlobalPose();
84 const Eigen::Matrix4f tcpInHandRoot = handRootPoseGlobal.inverse() * tcpPoseGlobal;
85
86 // get current pose of tcp
87 auto currentTCPPoseGlobal = robot->getRobotNode(tcpName)->getGlobalPose();
88
89 const auto tcpTargetPoseGlobal = in.parameters.targetPoseGlobal;
90 const Eigen::Matrix4f handRootTargetPoseGlobal =
91 tcpTargetPoseGlobal * tcpInHandRoot.inverse();
92
93 const float baseSpeedFactor = 1.5;
94 const float maxTranslationSpeed = baseSpeedFactor * 30;
95 const float minTranslationSpeed = maxTranslationSpeed * 0.1; // 10% of max
96 const float maxRotationSpeed = baseSpeedFactor * 0.7;
97 const float minRotationSpeed = maxRotationSpeed * 0.1; // 10% of max
98
99 // get translational difference
100 Eigen::Vector3f diffPos =
101 tcpTargetPoseGlobal.block<3, 1>(0, 3) - currentTCPPoseGlobal.block<3, 1>(0, 3);
102 float diffPosError = diffPos.norm();
103
104 float sig = 1 / (1 + pow(M_E, -diffPos.norm() / 5.f + 1.0)); // sigmoid
105 diffPos = baseSpeedFactor * diffPos * sig;
106
107 // Dont let it go to slow
108 if (diffPosError < minTranslationSpeed && diffPosError != 0)
109 {
110 diffPos *= (minTranslationSpeed / diffPosError);
111 }
112
113 else if (diffPosError > maxTranslationSpeed && diffPosError != 0)
114 {
115 diffPos *= (maxTranslationSpeed / diffPosError);
116 }
117
118 if (diffPosError < in.parameters.positionalAccuracy)
119 {
120 diffPos = Eigen::Vector3f::Zero();
121 }
122
123 FramedDirection cartesianVelocity(diffPos, GlobalFrame, "");
124
125 {
126 auto l = arviz.layer(layerName);
127 auto a = armarx::viz::Arrow("cartesianVelocity");
128 a.pose(currentTCPPoseGlobal);
129 a.direction(diffPos);
130 a.length(diffPos.norm() * 3);
131 l.add(a);
132
133 auto b = armarx::viz::Sphere("targetPose");
134 b.pose(tcpTargetPoseGlobal);
135 b.radius(diffPos.norm());
136 l.add(b);
137
138 auto o = armarx::viz::Robot("grasp");
139 o.file("RobotAPI", robotAPIHandFileName);
140 o.pose(handRootTargetPoseGlobal);
141 l.add(o);
142
143 arviz.commit(l);
144 }
145
146 Eigen::Vector3f angles(0, 0, 0);
147 //float axisRot = 0;
148
149 // get rotational difference
150 Eigen::Matrix3f diffRot = tcpTargetPoseGlobal.block<3, 3>(0, 0) *
151 currentTCPPoseGlobal.block<3, 3>(0, 0).inverse();
152 angles = VirtualRobot::MathTools::eigen3f2rpy(diffRot);
153 float anglesError = angles.norm();
154
155 ARMARX_IMPORTANT << VAROUT(angles);
156
157 //rotation diff around one axis
158 //Eigen::Matrix4f diffPose = Eigen::Matrix4f::Identity();
159 //diffPose.block<3, 3>(0, 0) = diffRot;
160 //Eigen::Vector3f axis;
161 //VirtualRobot::MathTools::eigen4f2axisangle(diffPose, axis, axisRot);
162
163 // Check velocities
164 if (anglesError < minRotationSpeed && anglesError != 0)
165 {
166 angles *= (minRotationSpeed / anglesError);
167 }
168
169 else if (anglesError > maxRotationSpeed && anglesError != 0)
170 {
171 angles *= (maxRotationSpeed / anglesError);
172 }
173
174 if (anglesError < in.parameters.orientationalAccuracy)
175 {
176 angles = Eigen::Vector3f::Zero();
177 }
178
179 FramedDirection angleVelocity(angles, GlobalFrame, "");
180
181 // // make sure we don't move the hand too low
182 // if (handPoseFromKinematicModelEigen(2,3) < 1000 && cartesianVelocity->z < 0)
183 // {
184 // ARMARX_IMPORTANT << "Hand too low, moving it up a bit";
185 // if (handPoseFromKinematicModelEigen(2,3) < 950) cartesianVelocity->z = 0.1f*maxSpeed;
186 // else cartesianVelocity->z = 0.05f*maxSpeed;
187 // }
188
189 auto cartesianError = diffPosError;
190 auto angleError = anglesError; // axisRot
191
192 ARMARX_INFO << deactivateSpam(0.5) << "Distance to target: "
193 << (std::to_string(cartesianError) + " mm, " +
194 std::to_string(angleError * 180 / M_PI) + " deg")
195 << ", \n"
196 << "Elapsed time: "
197 << (armarx::core::time::DateTime::Now() - started).toMilliSeconds() << "\n"
198 << "Current Thresholds: " << in.parameters.positionalAccuracy << "mm, "
199 << in.parameters.orientationalAccuracy * 180.0f / M_PI << "deg";
200
201 ARMARX_INFO << deactivateSpam(0.5) << "Request to move TCP: angle vel: (" << angleVelocity.x
202 << ", " << angleVelocity.y << ", " << angleVelocity.z << ")\n"
203 << "catesian vel: " << cartesianVelocity.x << ", " << cartesianVelocity.y
204 << ", " << cartesianVelocity.z << ")";
205
206 if (angleError <= in.parameters.orientationalAccuracy &&
207 cartesianError <= in.parameters.positionalAccuracy)
208 {
210 }
211
212 context.tcpControlUnitPrx->setTCPVelocity(in.parameters.kinematicChainName,
213 tcpName,
214 new FramedDirection(cartesianVelocity),
215 new FramedDirection(angleVelocity));
217 }
218
220 MoveTCPToTargetPose::exit(const SpecializedExitInput& in)
221 {
222 clearLayer();
223
224 auto robot =
225 robotReader.getSynchronizedRobot(in.parameters.robotName,
227 VirtualRobot::RobotIO::RobotDescription::eStructure);
228 if (!robot)
229 {
230 ARMARX_WARNING << "Unable to get robot from robotstatememory. Abort exit method.";
231 return {.status = TerminatedSkillStatus::Failed};
232 }
233
234 std::string tcpName =
235 robot->getRobotNodeSet(in.parameters.kinematicChainName)->getTCP()->getName();
236
237 stopTCPMovement(in.parameters.kinematicChainName, tcpName);
238
239 if (!tcpControlUnitRequestedOnStart)
240 {
241 context.tcpControlUnitPrx->release();
242 }
243
244 return {.status = TerminatedSkillStatus::Succeeded};
245 }
246} // namespace armarx::skills
#define M_PI
Definition MathTools.h:17
#define VAROUT(x)
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
Definition Duration.cpp:48
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition Logging.cpp:99
The memory name system (MNS) client.
virtual void connect(armem::client::MemoryNameSystem &memoryNameSystem)
static DateTime Now()
Definition DateTime.cpp:51
Represents a frequency.
Definition Frequency.h:17
MoveTCPToTargetPose(armem::client::MemoryNameSystem &mns, armarx::viz::Client &arviz, TCPControlSkillContext &context)
SimplePeriodicSpecializedSkill(const SkillDescription &skillDescription, const armarx::Frequency &frequency)
armarx::core::time::DateTime started
Definition Skill.h:356
virtual InitResult init()
Override this method with the actual implementation.
Definition Skill.cpp:519
virtual ExitResult exit()
Override this method with the actual implementation.
Definition Skill.cpp:535
TCPControlSkill(armem::client::MemoryNameSystem &mns, armarx::viz::Client &arviz, const std::string &layerName, TCPControlSkillContext &c)
void stopTCPMovement(const std::string &kinematicChainName, const std::string &tcpName)
TCPControlSkillContext & context
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
std::string const GlobalFrame
Variable of the global coordinate system.
Definition FramedPose.h:65
const VariantTypeId FramedDirection
Definition FramedPose.h:37
double a(double t, double a0, double j)
Definition CtrlUtil.h:45
This file is part of ArmarX.
This file offers overloads of toIce() and fromIce() functions for STL container types.
A result struct for skill exit function.
Definition Skill.h:69
A result struct for skill initialization.
Definition Skill.h:50
TCPControlUnitInterfacePrx tcpControlUnitPrx
armem::client::MemoryNameSystem & mns
armem::robot_state::VirtualRobotReader robotReader