CartesianPositionController.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T),
5 * Karlsruhe Institute of Technology (KIT), all rights reserved.
6 *
7 * ArmarX is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * ArmarX is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * @author Simon Ottenhaus (simon dot ottenhaus at kit dot edu)
20 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
21 * GNU General Public License
22 */
23
25
26#include <VirtualRobot/IK/DifferentialIK.h>
27#include <VirtualRobot/Nodes/RobotNode.h>
28#include <VirtualRobot/Robot.h>
29#include <VirtualRobot/RobotNodeSet.h>
30
32
34
35namespace armarx
36{
38 const VirtualRobot::RobotNodePtr& tcp,
39 const VirtualRobot::RobotNodePtr& referenceFrame) :
40 tcp(tcp), referenceFrame(referenceFrame ? referenceFrame : tcp->getRobot()->getRootNode())
41 {
42 }
43
44 Eigen::VectorXf
45 CartesianPositionController::calculate(const Eigen::Matrix4f& targetPose,
46 VirtualRobot::IKSolver::CartesianSelection mode) const
47 {
49 int posLen = mode & VirtualRobot::IKSolver::Position ? 3 : 0;
50 int oriLen = mode & VirtualRobot::IKSolver::Orientation ? 3 : 0;
51 Eigen::VectorXf cartesianVel(posLen + oriLen);
52
53 if (posLen)
54 {
56 Eigen::Vector3f targetPos = targetPose.block<3, 1>(0, 3);
57 Eigen::Vector3f currentPos = tcp->getPositionInFrame(referenceFrame);
58 Eigen::Vector3f errPos = targetPos - currentPos;
59 Eigen::Vector3f posVel = errPos * KpPos;
60 if (maxPosVel > 0)
61 {
62 posVel = math::MathUtils::LimitTo(posVel, maxPosVel);
63 }
64 cartesianVel.block<3, 1>(0, 0) = posVel;
65 }
66
67 if (oriLen)
68 {
70 Eigen::Matrix3f targetOri = targetPose.block<3, 3>(0, 0);
71 Eigen::Matrix3f tcpOri = tcp->getPoseInFrame(referenceFrame).block<3, 3>(0, 0);
72 Eigen::Matrix3f oriDir = targetOri * tcpOri.inverse();
73 Eigen::AngleAxisf aa(oriDir);
74 Eigen::Vector3f errOri = aa.axis() * aa.angle();
75 Eigen::Vector3f oriVel = errOri * KpOri;
76
77 if (maxOriVel > 0)
78 {
79 oriVel = math::MathUtils::LimitTo(oriVel, maxOriVel);
80 }
81 cartesianVel.block<3, 1>(posLen, 0) = oriVel;
82 }
83 return cartesianVel;
84 }
85
86 Eigen::VectorXf
87 CartesianPositionController::calculatePos(const Eigen::Vector3f& targetPos) const
88 {
90 Eigen::VectorXf cartesianVel(3);
91 Eigen::Vector3f currentPos = tcp->getPositionInFrame(referenceFrame);
92 Eigen::Vector3f errPos = targetPos - currentPos;
93 Eigen::Vector3f posVel = errPos * KpPos;
94 if (maxPosVel > 0)
95 {
97 posVel = math::MathUtils::LimitTo(posVel, maxPosVel);
98 }
99 cartesianVel.block<3, 1>(0, 0) = posVel;
100 return cartesianVel;
101 }
102
103 float
104 CartesianPositionController::getPositionError(const Eigen::Matrix4f& targetPose) const
105 {
106 return GetPositionError(targetPose, tcp, referenceFrame);
107 }
108
109 float
110 CartesianPositionController::getOrientationError(const Eigen::Matrix4f& targetPose) const
111 {
112 return GetOrientationError(targetPose, tcp, referenceFrame);
113 }
114
115 float
116 CartesianPositionController::GetPositionError(const Eigen::Matrix4f& targetPose,
117 const VirtualRobot::RobotNodePtr& tcp,
118 const VirtualRobot::RobotNodePtr& referenceFrame)
119 {
121 Eigen::Vector3f targetPos = targetPose.block<3, 1>(0, 3);
122 Eigen::Vector3f tcpPos = referenceFrame ? tcp->getPositionInFrame(referenceFrame)
123 : tcp->getPositionInRootFrame();
124 Eigen::Vector3f errPos = targetPos - tcpPos;
125 return errPos.norm();
126 }
127
128 float
130 const Eigen::Matrix4f& targetPose,
131 const VirtualRobot::RobotNodePtr& tcp,
132 const VirtualRobot::RobotNodePtr& referenceFrame)
133 {
135 Eigen::Matrix3f targetOri = targetPose.block<3, 3>(0, 0);
136 Eigen::Matrix4f tcpPose =
137 referenceFrame ? tcp->getPoseInFrame(referenceFrame) : tcp->getPoseInRootFrame();
138 Eigen::Matrix3f tcpOri = tcpPose.block<3, 3>(0, 0);
139 Eigen::Matrix3f oriDir = targetOri * tcpOri.inverse();
140 Eigen::AngleAxisf aa(oriDir);
141 return aa.angle();
142 }
143
144 bool
145 CartesianPositionController::Reached(const Eigen::Matrix4f& targetPose,
146 const VirtualRobot::RobotNodePtr& tcp,
147 bool checkOri,
148 float thresholdPosReached,
149 float thresholdOriReached,
150 const VirtualRobot::RobotNodePtr& referenceFrame)
151 {
152 return GetPositionError(targetPose, tcp, referenceFrame) < thresholdPosReached &&
153 (!checkOri ||
154 GetOrientationError(targetPose, tcp, referenceFrame) < thresholdOriReached);
155 }
156
157 bool
158 CartesianPositionController::reached(const Eigen::Matrix4f& targetPose,
159 VirtualRobot::IKSolver::CartesianSelection mode,
160 float thresholdPosReached,
161 float thresholdOriReached)
162 {
164 if (mode & VirtualRobot::IKSolver::Position)
165 {
166 if (GetPositionError(targetPose, tcp, referenceFrame) > thresholdPosReached)
167 {
168 return false;
169 }
170 }
171 if (mode & VirtualRobot::IKSolver::Orientation)
172 {
173 if (GetOrientationError(targetPose, tcp, referenceFrame) > thresholdOriReached)
174 {
175 return false;
176 }
177 }
178 return true;
179 }
180
181 Eigen::Vector3f
182 CartesianPositionController::getPositionDiff(const Eigen::Matrix4f& targetPose) const
183 {
185 Eigen::Vector3f targetPos = targetPose.block<3, 1>(0, 3);
186 return targetPos - tcp->getPositionInFrame(referenceFrame);
187 }
188
189 Eigen::Vector3f
190 CartesianPositionController::getPositionDiffVec3(const Eigen::Vector3f& targetPosition) const
191 {
192 return targetPosition - tcp->getPositionInFrame(referenceFrame);
193 }
194
195 Eigen::Vector3f
196 CartesianPositionController::getOrientationDiff(const Eigen::Matrix4f& targetPose) const
197 {
199 Eigen::Matrix3f targetOri = targetPose.block<3, 3>(0, 0);
200 Eigen::Matrix3f tcpOri = tcp->getPoseInFrame(referenceFrame).block<3, 3>(0, 0);
201 Eigen::Matrix3f oriDir = targetOri * tcpOri.inverse();
202 Eigen::AngleAxisf aa(oriDir);
203 return aa.axis() * aa.angle();
204 }
205
206 VirtualRobot::RobotNodePtr
208 {
209 return tcp;
210 }
211
212#define SS_OUT(x) ss << #x << " = " << x << "\n"
213#define SET_FLT(x) obj->setFloat(#x, x)
214#define GET_FLT(x) x = obj->getFloat(#x);
215
219
220 std::string
222 {
223 std::stringstream ss;
224
225 SS_OUT(KpPos);
226 SS_OUT(KpOri);
227 SS_OUT(maxPosVel);
228 SS_OUT(maxOriVel);
229 SS_OUT(thresholdOrientationNear);
230 SS_OUT(thresholdOrientationReached);
231 SS_OUT(thresholdPositionNear);
232 SS_OUT(thresholdPositionReached);
233
234 return ss.str();
235 }
236
237 void
238 CartesianPositionControllerConfig::serialize(const ObjectSerializerBasePtr& serializer,
239 const Ice::Current&) const
240 {
241 AbstractObjectSerializerPtr obj = AbstractObjectSerializerPtr::dynamicCast(serializer);
242
243 SET_FLT(KpPos);
244 SET_FLT(KpOri);
245 SET_FLT(maxPosVel);
246 SET_FLT(maxOriVel);
247 SET_FLT(thresholdOrientationNear);
248 SET_FLT(thresholdOrientationReached);
249 SET_FLT(thresholdPositionNear);
250 SET_FLT(thresholdPositionReached);
251 }
252
253 void
254 CartesianPositionControllerConfig::deserialize(const ObjectSerializerBasePtr& serializer,
255 const Ice::Current&)
256 {
257 AbstractObjectSerializerPtr obj = AbstractObjectSerializerPtr::dynamicCast(serializer);
258
259 GET_FLT(KpPos);
260 GET_FLT(KpOri);
261 GET_FLT(maxPosVel);
262 GET_FLT(maxOriVel);
263 GET_FLT(thresholdOrientationNear);
264 GET_FLT(thresholdOrientationReached);
265 GET_FLT(thresholdPositionNear);
266 GET_FLT(thresholdPositionReached);
267 }
268} // namespace armarx
#define SS_OUT(x)
#define SET_FLT(x)
#define GET_FLT(x)
void deserialize(const armarx::ObjectSerializerBasePtr &serializer, const ::Ice::Current &=::Ice::Current()) override
std::string output(const Ice::Current &c=::Ice::Current()) const override
void serialize(const armarx::ObjectSerializerBasePtr &serializer, const ::Ice::Current &=::Ice::Current()) const override
static float GetOrientationError(const Eigen::Matrix4f &targetPose, const VirtualRobot::RobotNodePtr &tcp, const VirtualRobot::RobotNodePtr &referenceFrame=nullptr)
Eigen::Vector3f getPositionDiffVec3(const Eigen::Vector3f &targetPosition) const
float getPositionError(const Eigen::Matrix4f &targetPose) const
Eigen::VectorXf calculatePos(const Eigen::Vector3f &targetPos) const
Eigen::VectorXf calculate(const Eigen::Matrix4f &targetPose, VirtualRobot::IKSolver::CartesianSelection mode) const
static bool Reached(const Eigen::Matrix4f &targetPose, const VirtualRobot::RobotNodePtr &tcp, bool checkOri, float thresholdPosReached, float thresholdOriReached, const VirtualRobot::RobotNodePtr &referenceFrame=nullptr)
CartesianPositionController(const VirtualRobot::RobotNodePtr &tcp, const VirtualRobot::RobotNodePtr &referenceFrame=nullptr)
float getOrientationError(const Eigen::Matrix4f &targetPose) const
Eigen::Vector3f getOrientationDiff(const Eigen::Matrix4f &targetPose) const
bool reached(const Eigen::Matrix4f &targetPose, VirtualRobot::IKSolver::CartesianSelection mode, float thresholdPosReached, float thresholdOriReached)
Eigen::Vector3f getPositionDiff(const Eigen::Matrix4f &targetPose) const
VirtualRobot::RobotNodePtr getTcp() const
static float GetPositionError(const Eigen::Matrix4f &targetPose, const VirtualRobot::RobotNodePtr &tcp, const VirtualRobot::RobotNodePtr &referenceFrame=nullptr)
static double LimitTo(double value, double absThreshold)
Definition MathUtils.h:71
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< AbstractObjectSerializer > AbstractObjectSerializerPtr
#define ARMARX_TRACE
Definition trace.h:77