VisualServoTCPToTargetPose.cpp
Go to the documentation of this file.
2
3#include <VirtualRobot/MathTools.h>
4#include <VirtualRobot/RobotNodeSet.h>
5
8
10
11namespace armarx::skills
12{
13 namespace
14 {
15 visual_servo_tcp_control::arondto::MoveTCPToTargetPoseAcceptedType
16 GetDefaultParameterization()
17 {
18 visual_servo_tcp_control::arondto::MoveTCPToTargetPoseAcceptedType ret;
19 ret.orientationalAccuracy = 0.01;
20 ret.positionalAccuracy = 25;
21 return ret;
22 }
23 } // namespace
24
26 .skillId = {.skillName = "VisualServoToTargetPose"},
27 .description = "Visual Servo the TCP to a target pose",
28 .rootProfileDefaults = GetDefaultParameterization().toAron(),
29 .timeout = armarx::Duration::MilliSeconds(2000),
30 .parametersType = visual_servo_tcp_control::arondto::MoveTCPToTargetPoseAcceptedType::ToAronType(),
31 };
32
43
45 VisualServoToTargetPose::init(const SpecializedInitInput& in)
46 {
47 robotReader.connect(mns);
48 objectReader.connect(mns);
49
50 tcpControlUnitRequestedOnStart = true;
51 if (!context.tcpControlUnitPrx->isRequested())
52 {
53 tcpControlUnitRequestedOnStart = false;
54 context.tcpControlUnitPrx->request();
55 }
56 context.tcpControlUnitPrx->setCycleTime(20);
57
58 return {.status = TerminatedSkillStatus::Succeeded};
59 }
60
62 VisualServoToTargetPose::step(const SpecializedMainInput& in)
63 {
65
66 /*auto robot = robotReader.getSynchronizedRobot(in.parameters.robotName, armem::Time::Now(), VirtualRobot::RobotIO::RobotDescription::eStructure);
67 if (!robot)
68 {
69 ARMARX_WARNING << "Unable to get robot from robotstatememory. Abort.";
70 return {ActiveOrTerminatedSkillStatus::Failed, nullptr};
71 }
72
73 std::string tcpName = robot->getRobotNodeSet(in.parameters.kinematicChainName)->getTCP()->getName();
74
75 const Eigen::Matrix4f tcpPoseGlobal = robot->getRobotNode(tcpName)->getGlobalPose();
76 const Eigen::Matrix4f handRootPoseGlobal = robot->getRobotNode(in.parameters.handRootNodeName)->getGlobalPose();
77 const Eigen::Matrix4f tcpInHandRoot = handRootPoseGlobal.inverse() * tcpPoseGlobal;
78
79 ARMARX_CHECK(robotReader.synchronizeRobot(*robot, armem::Time::Now()));
80
81 // get current pose of tcp
82 auto currentTCPPoseGlobal = robot->getRobotNode(tcpName)->getGlobalPose();
83
84 // get hand from memory
85 auto handInstance = objectReader.queryObjectByObjectID(tcpName, armem::Time::Now());
86 if (handInstance)
87 {
88 currentTCPPoseGlobal = handInstance->pose.objectPoseGlobal;
89 }
90
91
92 const auto tcpTargetPoseGlobal = in.parameters.targetPoseGlobal;
93 const Eigen::Matrix4f handRootTargetPoseGlobal = tcpTargetPoseGlobal * tcpInHandRoot.inverse();
94
95 const float baseSpeedFactor = 1.0;
96 const float maxTranslationSpeed = baseSpeedFactor * 30;
97 const float minTranslationSpeed = maxTranslationSpeed * 10;
98 const float maxRotationSpeed = baseSpeedFactor * 0.7;
99 const float minRotationSpeed = maxRotationSpeed * 0.1;
100
101 // get translational difference
102 Eigen::Vector3f diffPos = tcpTargetPoseGlobal.block<3, 1>(0, 3) - currentTCPPoseGlobal.block<3, 1>(0, 3);
103
104 float sig = 1 / (1 + pow(M_E, -diffPos.norm() / 5.f + 1.0)); // sigmoid
105 diffPos = baseSpeedFactor * diffPos * sig;
106
107 // Check if target reached
108 if (diffPos.norm() < in.parameters.positionalAccuracy)
109 {
110 diffPos = Eigen::Vector3f::Zero();
111 }
112
113 // Dont let it go to slow
114 if (diffPos.norm() < minTranslationSpeed && diffPos.norm() != 0)
115 {
116 diffPos = diffPos * (minTranslationSpeed / diffPos.norm());
117 }
118
119 if (diffPos.norm() > maxTranslationSpeed && diffPos.norm() != 0)
120 {
121 diffPos = diffPos * (maxTranslationSpeed / diffPos.norm());
122 }
123
124 FramedDirection cartesianVelocity(diffPos, GlobalFrame, "");
125
126 {
127 auto l = arviz.layer(layerName);
128 auto a = armarx::viz::Arrow("cartesianVelocity");
129 a.pose(currentTCPPoseGlobal);
130 a.direction(diffPos);
131 a.length(diffPos.norm()*3);
132 l.add(a);
133
134 auto b = armarx::viz::Sphere("targetPose");
135 b.pose(tcpTargetPoseGlobal);
136 b.radius(diffPos.norm());
137 l.add(b);
138
139 auto o = armarx::viz::Robot("grasp");
140 o.file("RobotAPI", in.parameters.handFileName);
141 o.pose(handRootTargetPoseGlobal);
142 l.add(o);
143
144 arviz.commit(l);
145 }
146
147 Eigen::Vector3f angles(0, 0, 0);
148 //float axisRot = 0;
149
150 // get rotational difference
151 Eigen::Matrix3f diffRot = tcpTargetPoseGlobal.block<3, 3>(0, 0) * currentTCPPoseGlobal.block<3, 3>(0, 0).inverse();
152 angles = VirtualRobot::MathTools::eigen3f2rpy(diffRot);
153
154 ARMARX_IMPORTANT << VAROUT(angles);
155
156 //rotation diff around one axis
157 //Eigen::Matrix4f diffPose = Eigen::Matrix4f::Identity();
158 //diffPose.block<3, 3>(0, 0) = diffRot;
159 //Eigen::Vector3f axis;
160 //VirtualRobot::MathTools::eigen4f2axisangle(diffPose, axis, axisRot);
161
162 // Check if target reached
163 if (angles.norm() < in.parameters.orientationalAccuracy)
164 {
165 angles = Eigen::Vector3f::Zero();
166 }
167
168 // Check velocities
169 if (angles.norm() < minRotationSpeed && angles.norm() != 0)
170 {
171 angles *= minRotationSpeed / angles.norm();
172 }
173
174 if (angles.norm() > maxRotationSpeed && angles.norm() != 0)
175 {
176 angles *= maxRotationSpeed / angles.norm();
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 = diffPos.norm();
190 auto angleError = angles.norm(); // axisRot
191
192
193 ARMARX_INFO << deactivateSpam(0.5) << "Distance to target: " << (std::to_string(cartesianError) + " mm, " + std::to_string(angleError * 180 / M_PI) + " deg") << ", \n" <<
194 "Elapsed time: " << (armarx::core::time::DateTime::Now() - started).toMilliSeconds() << "\n" <<
195 "Current Thresholds: " << in.parameters.positionalAccuracy << "mm, " << in.parameters.orientationalAccuracy * 180.0f / M_PI << "deg";
196
197 if (angleError <= in.parameters.orientationalAccuracy && cartesianError <= in.parameters.positionalAccuracy)
198 {
199 return {ActiveOrTerminatedSkillStatus::Succeeded, nullptr};
200 }
201
202 context.tcpControlUnitPrx->setTCPVelocity(in.parameters.kinematicChainName, tcpName, new FramedDirection(cartesianVelocity), new FramedDirection(angleVelocity));
203
204 return {ActiveOrTerminatedSkillStatus::Running, nullptr};*/
205 }
206
208 VisualServoToTargetPose::exit(const SpecializedExitInput& in)
209 {
210 clearLayer();
211
212 if (!tcpControlUnitRequestedOnStart)
213 {
214 context.tcpControlUnitPrx->release();
215 }
216
217 auto robot =
218 robotReader.getSynchronizedRobot(in.parameters.robotName,
220 VirtualRobot::RobotIO::RobotDescription::eStructure);
221 if (!robot)
222 {
223 ARMARX_WARNING << "Unable to get robot from robotstatememory. Abort exit method.";
224 return {.status = TerminatedSkillStatus::Failed};
225 }
226
227 std::string tcpName =
228 robot->getRobotNodeSet(in.parameters.kinematicChainName)->getTCP()->getName();
229
230 stopTCPMovement(in.parameters.kinematicChainName, tcpName);
231
232 return {.status = TerminatedSkillStatus::Succeeded};
233 }
234} // namespace armarx::skills
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
Definition Duration.cpp:48
The memory name system (MNS) client.
void connect(armem::client::MemoryNameSystem &memoryNameSystem)
virtual void connect(armem::client::MemoryNameSystem &memoryNameSystem)
static DateTime Now()
Definition DateTime.cpp:51
Represents a frequency.
Definition Frequency.h:17
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
void stopTCPMovement(const std::string &kinematicChainName, const std::string &tcpName)
TCPControlSkillContext & context
VisualServoTCPControlSkill(armem::client::MemoryNameSystem &mns, armarx::viz::Client &arviz, const std::string &layerName, VisualServoTCPControlSkillContext &c)
VisualServoToTargetPose(armem::client::MemoryNameSystem &mns, armarx::viz::Client &arviz, VisualServoTCPControlSkillContext &context)
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
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