TCPControlUnit.h
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 ArmarX::
17* @author Mirko Waechter (mirko.waechter at kit dot edu)
18* @date 2013
19* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20* GNU General Public License
21*/
22
23#pragma once
24
25#include <memory>
26
27#include <VirtualRobot/IK/DifferentialIK.h>
28#include <VirtualRobot/VirtualRobot.h>
29
32#include <ArmarXCore/interface/observers/ObserverInterface.h>
33
34#include <RobotAPI/interface/units/TCPControlUnit.h>
37
38namespace armarx
39{
40 /**
41 * \class TCPControlUnitPropertyDefinitions
42 * \brief
43 */
45 {
46 public:
48 {
49 defineRequiredProperty<std::string>("KinematicUnitName",
50 "Name of the KinematicUnit Proxy");
52 "RobotStateTopicName", "RobotState", "Name of the RobotComponent State topic.");
54 "MaxJointVelocity", 30.f / 180 * 3.141, "Maximal joint velocity in rad/sec");
55 defineOptionalProperty<int>("CycleTime", 30, "Cycle time of the tcp control in ms");
56 // defineOptionalProperty<float>("MaximumCommandDelay", 20000, "Delay after which the TCP Control unit releases itself if no new velocity have been set.");
58 "TCPsToReport",
59 "",
60 "comma seperated list of nodesets' endeffectors, which poses and velocities that "
61 "should be reported. * for all, empty for none");
63 "RobotStateComponentName",
64 "RobotStateComponent",
65 "Name of the RobotStateComponent that should be used");
66
68 "LambdaDampedSVD",
69 0.1f,
70 "Parameter used for smoothing the differential IK near singularities.");
71 }
72 };
73
74 /**
75 * \defgroup Component-TCPControlUnit TCPControlUnit
76 * \ingroup RobotAPI-SensorActorUnits
77 * \brief Unit for controlling a tool center point (TCP).
78 *
79 * This class implements the interface to control a node of a robot (e.g a TCP)
80 * in cartesian coordinates in velocity control mode. It takes velocities in mm/s for
81 * translations and rad/s for orientation. Several nodessets can be controlled simultaneously.
82 *
83 * Before the TCPControlUnit can be used, request() needs to be called. Since a cartesian velocity needs
84 * is only correct for the current joint configuration, it needs to recalculated as fast as possible.
85 * Thus, after request is called the TCPControlUnit recalculates the velocity in a given cycle time and
86 * updates the joint velocities. To set another cycle time use setCycleTime().
87 * To set the velocity for a node use setTCPVelocity. Calling setTCPVelocity again with another nodeset
88 * will add this nodeset to the list of currently controlled TCPs.
89 *
90 * \note After usage release() **must** be called to stop the recalcuation and setting of joint velocities.
91 */
92
93 /**
94 * @ingroup Component-TCPControlUnit
95 * @brief The TCPControlUnit class
96 */
97 class TCPControlUnit : virtual public Component, virtual public TCPControlUnitInterface
98 {
99 public:
101
102 // TCPControlUnitInterface interface
103
104 /**
105 * \brief Sets the cycle time with which the joint velocities are recalculated.
106 * \param milliseconds New cycle time.
107 * \param c Ice Context, leave blank.
108 */
109 void setCycleTime(Ice::Int milliseconds,
110 const Ice::Current& c = Ice::emptyCurrent) override;
111
112 /**
113 * \brief Sets the cartesian velocity of a node in a nodeset for translation and/or orientation.
114 * It is best to provide the data in global coordinates. Otherwise the coordinates frame transformation is done in place
115 * on the current robot state, which might not be the same as when the command was given. Additionally, execution inaccurracies
116 * might propagate if local coordinate frames are used.
117 * \param nodeSetName Nodeset that should be used for moving the node, i.e. tcp
118 * \param tcpName Name of the VirtualRobot node that should be moved
119 * \param translationVelocity Target cartesian translation velocity in mm/s, but might not be reached. If NULL the translation is ommitted in the calculation.
120 * Thus the translation behaviour is undefined und the node/tcp position might change.
121 * \param orientationVelocityRPY Target cartesian orientation velocity in rad/s in roll-pitch-yaw, but might not be reached. If NULL the orientation is ommitted in the calculation.
122 * Thus the orientation behaviour is undefined und the node/tcp orientation might change.
123 * \param c Ice Context, leave blank.
124 *
125 * \see request(), release()
126 */
127 void setTCPVelocity(const std::string& nodeSetName,
128 const std::string& tcpName,
129 const ::armarx::FramedDirectionBasePtr& translationVelocity,
130 const ::armarx::FramedDirectionBasePtr& orientationVelocityRPY,
131 const Ice::Current& c = Ice::emptyCurrent) override;
132
133 // UnitExecutionManagementInterface interface
134 /**
135 * \brief Does not do anything at the moment.
136 * \param c
137 */
138 void init(const Ice::Current& c = Ice::emptyCurrent) override;
139 /**
140 * \brief Does not do anything at the moment.
141 * \param c
142 */
143 void start(const Ice::Current& c = Ice::emptyCurrent) override;
144 /**
145 * \brief Does not do anything at the moment.
146 * \param c
147 */
148 void stop(const Ice::Current& c = Ice::emptyCurrent) override;
149 UnitExecutionState getExecutionState(const Ice::Current& c = Ice::emptyCurrent) override;
150
151 // UnitResourceManagementInterface interface
152 /**
153 * \brief Triggers the calculation loop for using cartesian velocity. Call once before/after setting a tcp velocity with SetTCPVelocity.
154 * \param c Ice Context, leave blank.
155 */
156 void request(const Ice::Current& c = Ice::emptyCurrent) override;
157
158 /**
159 * \brief Releases and stops the recalculation and updating of joint velocities.
160 * Call always when finished with cartesian control. The target velocity values of
161 * all node set will be deleted in this function.
162 * \param c Ice Context, leave blank.
163 */
164 void release(const Ice::Current& c = Ice::emptyCurrent) override;
165
166 bool isRequested(const Ice::Current& c = Ice::emptyCurrent) override;
167
168 protected:
169 void onInitComponent() override;
170 void onConnectComponent() override;
171 void onDisconnectComponent() override;
172 void onExitComponent() override;
173
174 std::string
175 getDefaultName() const override
176 {
177 return "TCPControlUnit";
178 }
179
180 // PropertyUser interface
182
183 static Eigen::VectorXf CalcNullspaceJointDeltas(const Eigen::VectorXf& desiredJointDeltas,
184 const Eigen::MatrixXf& jacobian,
185 const Eigen::MatrixXf& jacobianInverse);
186 static Eigen::VectorXf
187 CalcJointLimitAvoidanceDeltas(VirtualRobot::RobotNodeSetPtr robotNodeSet,
188 const Eigen::MatrixXf& jacobian,
189 const Eigen::MatrixXf& jacobianInverse,
190 Eigen::VectorXf desiredJointValues = Eigen::VectorXf());
192
193 private:
194 static void ContinuousAngles(const Eigen::AngleAxisf& oldAngle,
195 Eigen::AngleAxisf& newAngle,
196 double& offset);
197 void periodicExec();
198 void periodicReport();
199 Eigen::VectorXf calcJointVelocities(VirtualRobot::RobotNodeSetPtr robotNodeSet,
200 Eigen::VectorXf tcpDelta,
201 VirtualRobot::RobotNodePtr refFrame,
202 VirtualRobot::IKSolver::CartesianSelection mode);
203 Eigen::VectorXf applyMaxJointVelocity(const Eigen::VectorXf& jointVelocity,
204 float maxJointVelocity);
205
206 float maxJointVelocity;
207 int cycleTime;
208 Eigen::Matrix4f lastTCPPose;
209
210 struct TCPVelocityData
211 {
212 FramedDirectionPtr translationVelocity;
213 FramedDirectionPtr orientationVelocity;
214 std::string nodeSetName;
215 std::string tcpName;
216 };
217
218 using TCPVelocityDataMap = std::map<std::string, TCPVelocityData>;
219 TCPVelocityDataMap tcpVelocitiesMap, localTcpVelocitiesMap;
220
221 using DIKMap = std::map<std::string, VirtualRobot::DifferentialIKPtr>;
222 DIKMap dIKMap, localDIKMap;
223
224
227 std::string robotName;
228 RobotStateComponentInterfacePrx robotStateComponentPrx;
229 KinematicUnitInterfacePrx kinematicUnitPrx;
230 VirtualRobot::RobotPtr jointExistenceCheckRobot;
231 VirtualRobot::RobotPtr localRobot;
232 VirtualRobot::RobotPtr localReportRobot;
233 VirtualRobot::RobotPtr localVelReportRobot;
234 TCPControlUnitListenerPrx listener;
235
237
238 bool requested;
239 std::map<std::string, double> oriOffsets;
240
241 std::vector<VirtualRobot::RobotNodePtr> nodesToReport;
242 FramedPoseBaseMap lastTCPPoses;
243 IceUtil::Time lastTopicReportTime;
244
245 std::mutex dataMutex;
246 std::mutex taskMutex;
247 std::mutex reportMutex;
248 bool calculationRunning;
249 double syncTimeDelta;
250
251 std::string topicName;
252
253
254 // KinematicUnitListener interface
255 protected:
256 void reportControlModeChanged(const NameControlModeMap&,
257 Ice::Long timestamp,
258 bool,
259 const Ice::Current&) override;
260 void reportJointAngles(const NameValueMap& jointAngles,
261 Ice::Long timestamp,
262 bool,
263 const Ice::Current&) override;
264 void reportJointVelocities(const NameValueMap& jointVel,
265 Ice::Long timestamp,
266 bool,
267 const Ice::Current&) override;
268 void reportJointTorques(const NameValueMap&,
269 Ice::Long timestamp,
270 bool,
271 const Ice::Current&) override;
272 void reportJointAccelerations(const NameValueMap& jointAccelerations,
273 Ice::Long timestamp,
274 bool aValueChanged,
275 const Ice::Current& c) override;
276 void reportJointCurrents(const NameValueMap&,
277 Ice::Long timestamp,
278 bool,
279 const Ice::Current&) override;
280 void reportJointMotorTemperatures(const NameValueMap&,
281 Ice::Long timestamp,
282 bool,
283 const Ice::Current&) override;
284 void reportJointStatuses(const NameStatusMap&,
285 Ice::Long timestamp,
286 bool,
287 const Ice::Current&) override;
288 };
289
290 class EDifferentialIK : public VirtualRobot::DifferentialIK, virtual public Logging
291 {
292 public:
293 typedef Eigen::VectorXf (EDifferentialIK::*ComputeFunction)(float);
294
295 EDifferentialIK(VirtualRobot::RobotNodeSetPtr rns,
296 VirtualRobot::RobotNodePtr coordSystem = VirtualRobot::RobotNodePtr(),
297 VirtualRobot::JacobiProvider::InverseJacobiMethod invJacMethod = eSVD);
298
299 VirtualRobot::RobotNodePtr
301 {
302 return coordSystem;
303 }
304
305 int
307 {
308 return nRows;
309 }
310
311 Eigen::MatrixXf calcFullJacobian();
312
313 void clearGoals();
314 void setRefFrame(VirtualRobot::RobotNodePtr coordSystem);
315
316 void setGoal(const Eigen::Matrix4f& goal,
317 VirtualRobot::RobotNodePtr tcp,
318 VirtualRobot::IKSolver::CartesianSelection mode,
319 float tolerancePosition,
320 float toleranceRotation,
321 Eigen::VectorXf tcpWeight);
322
323 void setDOFWeights(Eigen::VectorXf dofWeights);
324 // void setTCPWeights(Eigen::VectorXf tcpWeights);
325 bool
326 computeSteps(float stepSize = 1.f, float mininumChange = 0.01f, int maxNStep = 50) override;
327 bool computeSteps(Eigen::VectorXf& resultJointDelta,
328 float stepSize = 1.f,
329 float mininumChange = 0.01f,
330 int maxNStep = 50,
331 ComputeFunction computeFunction = &DifferentialIK::computeStep);
332 Eigen::VectorXf computeStep(float stepSize) override;
333 void applyDOFWeightsToJacobian(Eigen::MatrixXf& Jacobian);
334 void applyTCPWeights(VirtualRobot::RobotNodePtr tcp, Eigen::MatrixXf& partJacobian);
335 void applyTCPWeights(Eigen::MatrixXf& invJacobian);
336 float getWeightedError();
337 float getWeightedErrorPosition(VirtualRobot::SceneObjectPtr tcp);
338 Eigen::VectorXf computeStepIndependently(float stepSize);
339 bool solveIK(float stepSize = 1,
340 float minChange = 0.01f,
341 int maxSteps = 50,
342 bool useAlternativeOnFail = false);
343
344 protected:
345 bool adjustDOFWeightsToJointLimits(const Eigen::VectorXf& plannedJointDeltas);
346
347 Eigen::VectorXf dofWeights;
348 std::map<VirtualRobot::SceneObjectPtr, Eigen::VectorXf> tcpWeights;
349 Eigen::VectorXf tcpWeightVec;
350 };
351
352 using EDifferentialIKPtr = std::shared_ptr<EDifferentialIK>;
353
354} // namespace armarx
#define float
Definition 16_Level.h:22
std::string timestamp()
constexpr T c
ComponentPropertyDefinitions(std::string prefix, bool hasObjectNameParameter=true)
Definition Component.cpp:46
Component()
Protected default constructor. Used for virtual inheritance. Use createManagedIceObject() instead.
Definition Component.cpp:66
Eigen::VectorXf computeStep(float stepSize) override
bool computeSteps(Eigen::VectorXf &resultJointDelta, float stepSize=1.f, float mininumChange=0.01f, int maxNStep=50, ComputeFunction computeFunction=&DifferentialIK::computeStep)
std::map< VirtualRobot::SceneObjectPtr, Eigen::VectorXf > tcpWeights
void setGoal(const Eigen::Matrix4f &goal, VirtualRobot::RobotNodePtr tcp, VirtualRobot::IKSolver::CartesianSelection mode, float tolerancePosition, float toleranceRotation, Eigen::VectorXf tcpWeight)
void applyDOFWeightsToJacobian(Eigen::MatrixXf &Jacobian)
Eigen::VectorXf tcpWeightVec
bool solveIK(float stepSize=1, float minChange=0.01f, int maxSteps=50, bool useAlternativeOnFail=false)
Eigen::VectorXf(EDifferentialIK::* ComputeFunction)(float)
VirtualRobot::RobotNodePtr getRefFrame()
void applyTCPWeights(VirtualRobot::RobotNodePtr tcp, Eigen::MatrixXf &partJacobian)
bool adjustDOFWeightsToJointLimits(const Eigen::VectorXf &plannedJointDeltas)
Eigen::VectorXf computeStepIndependently(float stepSize)
float getWeightedErrorPosition(VirtualRobot::SceneObjectPtr tcp)
Eigen::MatrixXf calcFullJacobian()
void setRefFrame(VirtualRobot::RobotNodePtr coordSystem)
void applyTCPWeights(Eigen::MatrixXf &invJacobian)
EDifferentialIK(VirtualRobot::RobotNodeSetPtr rns, VirtualRobot::RobotNodePtr coordSystem=VirtualRobot::RobotNodePtr(), VirtualRobot::JacobiProvider::InverseJacobiMethod invJacMethod=eSVD)
bool computeSteps(float stepSize=1.f, float mininumChange=0.01f, int maxNStep=50) override
Eigen::VectorXf dofWeights
void setDOFWeights(Eigen::VectorXf dofWeights)
IceUtil::Handle< PeriodicTask< T > > pointer_type
Shared pointer type for convenience.
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
PropertyDefinition< PropertyType > & defineOptionalProperty(const std::string &name, PropertyType defaultValue, const std::string &description="", PropertyDefinitionBase::PropertyConstness constness=PropertyDefinitionBase::eConstant)
PropertyDefinition< PropertyType > & defineRequiredProperty(const std::string &name, const std::string &description="", PropertyDefinitionBase::PropertyConstness constness=PropertyDefinitionBase::eConstant)
TCPControlUnitPropertyDefinitions(std::string prefix)
void onInitComponent() override
Pure virtual hook for the subclass.
static Eigen::VectorXf CalcNullspaceJointDeltas(const Eigen::VectorXf &desiredJointDeltas, const Eigen::MatrixXf &jacobian, const Eigen::MatrixXf &jacobianInverse)
void start(const Ice::Current &c=Ice::emptyCurrent) override
Does not do anything at the moment.
void release(const Ice::Current &c=Ice::emptyCurrent) override
Releases and stops the recalculation and updating of joint velocities.
UnitExecutionState getExecutionState(const Ice::Current &c=Ice::emptyCurrent) override
void reportJointMotorTemperatures(const NameValueMap &, Ice::Long timestamp, bool, const Ice::Current &) override
void reportControlModeChanged(const NameControlModeMap &, Ice::Long timestamp, bool, const Ice::Current &) override
void onDisconnectComponent() override
Hook for subclass.
static Eigen::VectorXf CalcJointLimitAvoidanceDeltas(VirtualRobot::RobotNodeSetPtr robotNodeSet, const Eigen::MatrixXf &jacobian, const Eigen::MatrixXf &jacobianInverse, Eigen::VectorXf desiredJointValues=Eigen::VectorXf())
void init(const Ice::Current &c=Ice::emptyCurrent) override
Does not do anything at the moment.
void setCycleTime(Ice::Int milliseconds, const Ice::Current &c=Ice::emptyCurrent) override
Sets the cycle time with which the joint velocities are recalculated.
void reportJointTorques(const NameValueMap &, Ice::Long timestamp, bool, const Ice::Current &) override
void stop(const Ice::Current &c=Ice::emptyCurrent) override
Does not do anything at the moment.
void reportJointAngles(const NameValueMap &jointAngles, Ice::Long timestamp, bool, const Ice::Current &) override
void setTCPVelocity(const std::string &nodeSetName, const std::string &tcpName, const ::armarx::FramedDirectionBasePtr &translationVelocity, const ::armarx::FramedDirectionBasePtr &orientationVelocityRPY, const Ice::Current &c=Ice::emptyCurrent) override
Sets the cartesian velocity of a node in a nodeset for translation and/or orientation.
bool isRequested(const Ice::Current &c=Ice::emptyCurrent) override
void onConnectComponent() override
Pure virtual hook for the subclass.
void request(const Ice::Current &c=Ice::emptyCurrent) override
Triggers the calculation loop for using cartesian velocity.
void reportJointAccelerations(const NameValueMap &jointAccelerations, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c) override
PropertyDefinitionsPtr createPropertyDefinitions() override
void onExitComponent() override
Hook for subclass.
void reportJointCurrents(const NameValueMap &, Ice::Long timestamp, bool, const Ice::Current &) override
std::string getDefaultName() const override
Retrieve default name of component.
void reportJointStatuses(const NameStatusMap &, Ice::Long timestamp, bool, const Ice::Current &) override
void reportJointVelocities(const NameValueMap &jointVel, Ice::Long timestamp, bool, const Ice::Current &) override
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
This file offers overloads of toIce() and fromIce() functions for STL container types.
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugObserverInterface > DebugObserverInterfacePrx
IceInternal::Handle< FramedDirection > FramedDirectionPtr
Definition FramedPose.h:84
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
::IceInternal::ProxyHandle<::IceProxy::armarx::RobotStateComponentInterface > RobotStateComponentInterfacePrx
std::shared_ptr< EDifferentialIK > EDifferentialIKPtr
::std::map<::std::string, ::armarx::FramedPoseBasePtr > FramedPoseBaseMap