RobotStateObserver.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 ArmarX::Core
17* @author Stefan Ulbrich <stefan dot ulbrich at kit dot edu>, Kai Welke (welke _at_ kit _dot_ edu)
18* @date 2011 Kai Welke
19* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20* GNU General Public License
21*/
22
23#include "RobotStateObserver.h"
24
25#include <SimoxUtility/algorithm/string/string_tools.h>
26#include <VirtualRobot/IK/DifferentialIK.h>
27#include <VirtualRobot/Nodes/RobotNode.h>
28#include <VirtualRobot/RobotConfig.h>
29#include <VirtualRobot/RobotNodeSet.h>
30#include <VirtualRobot/VirtualRobot.h>
31
38
39#include <RobotAPI/interface/core/RobotState.h>
42
43#define TCP_POSE_CHANNEL "TCPPose"
44#define TCP_TRANS_VELOCITIES_CHANNEL "TCPVelocities"
45
46
47using namespace armarx;
48using namespace VirtualRobot;
49
50// ********************************************************************
51// observer framework hooks
52// ********************************************************************
56
57void
59{
60
61 // register all checks
66}
67
68void
70{
71
72
73 offerChannel(TCP_POSE_CHANNEL, "TCP poses of the robot.");
74 offerChannel(TCP_TRANS_VELOCITIES_CHANNEL, "TCP velocities of the robot.");
75}
76
77// ********************************************************************
78// private methods
79// ********************************************************************
80
81
82void
84{
85 if (getState() < eManagedIceObjectStarting)
86 {
87 return;
88 }
89
90 if (!robot)
91 {
92 return;
93 }
94
95 std::unique_lock lock(dataMutex);
96 ReadLockPtr lock2 = robot->getReadLock();
97 FramedPoseBaseMap tcpPoses;
98 std::string rootFrame = robot->getRootNode()->getName();
99
100 //IceUtil::Time start = IceUtil::Time::now();
101 for (unsigned int i = 0; i < nodesToReport.size(); i++)
102 {
103 VirtualRobot::RobotNodePtr& node = nodesToReport.at(i).first;
104 const std::string& tcpName = node->getName();
105 const Eigen::Matrix4f& currentPose = node->getPoseInRootFrame();
106 tcpPoses[tcpName] = new FramedPose(currentPose, rootFrame, robot->getName());
107 FramedPosePtr::dynamicCast(tcpPoses[tcpName])
108 ->changeFrame(robot, nodesToReport.at(i).second);
109 }
110
111 udpatePoseDatafields(tcpPoses);
112}
113
114void
116{
117 // ARMARX_INFO << deactivateSpam() << "new tcp poses reported";
118 FramedPoseBaseMap::const_iterator it = poseMap.begin();
119
120 for (; it != poseMap.end(); it++)
121 {
122
123 FramedPosePtr vec = FramedPosePtr::dynamicCast(it->second);
124 const std::string& tcpName = it->first;
125
126 if (!existsDataField(TCP_POSE_CHANNEL, tcpName))
127 {
129 TCP_POSE_CHANNEL, tcpName, Variant(it->second), "Pose of " + tcpName);
130 }
131 else
132 {
133 setDataField(TCP_POSE_CHANNEL, tcpName, Variant(it->second));
134 }
135
137
138 if (!existsChannel(tcpName))
139 {
140 offerChannel(tcpName, "pose components of " + tcpName);
141 offerDataFieldWithDefault(tcpName, "x", Variant(vec->position->x), "X axis");
142 offerDataFieldWithDefault(tcpName, "y", Variant(vec->position->y), "Y axis");
143 offerDataFieldWithDefault(tcpName, "z", Variant(vec->position->z), "Z axis");
145 tcpName, "qx", Variant(vec->orientation->qx), "Quaternion part x");
147 tcpName, "qy", Variant(vec->orientation->qy), "Quaternion part y");
149 tcpName, "qz", Variant(vec->orientation->qz), "Quaternion part z");
151 tcpName, "qw", Variant(vec->orientation->qw), "Quaternion part w");
152 offerDataFieldWithDefault(tcpName, "frame", Variant(vec->frame), "Reference Frame");
153 }
154 else
155 {
156 StringVariantBaseMap newValues;
157 newValues["x"] = new Variant(vec->position->x);
158 newValues["y"] = new Variant(vec->position->y);
159 newValues["z"] = new Variant(vec->position->z);
160 newValues["qx"] = new Variant(vec->orientation->qx);
161 newValues["qy"] = new Variant(vec->orientation->qy);
162 newValues["qz"] = new Variant(vec->orientation->qz);
163 newValues["qw"] = new Variant(vec->orientation->qw);
164 newValues["frame"] = new Variant(vec->frame);
165 setDataFieldsFlatCopy(tcpName, newValues);
166 }
167
168 updateChannel(tcpName);
169 }
170}
171
172void
174 const AMD_RobotStateObserverInterface_getPoseDatafieldPtr& amd,
175 const std::string& nodeName,
176 const Ice::Current&) const
177{
178 addWorkerJob("RobotStateObserver::getPoseDatafield",
179 [this, amd, nodeName]
180 { return getDatafieldRefByName(TCP_POSE_CHANNEL, nodeName); });
181}
182
183void
184RobotStateObserver::updateNodeVelocities(const NameValueMap& jointVel, long timestampMicroSeconds)
185{
186 if (jointVel.empty())
187 {
188 return;
189 }
190 if (getState() < eManagedIceObjectStarting)
191 {
192 return;
193 }
194
195 std::unique_lock lock(dataMutex);
196
197 if (!robot)
198 {
199 return;
200 }
201
202 ReadLockPtr lock2 = robot->getReadLock();
203
204 if (!velocityReportRobot)
205 {
206 velocityReportRobot = robot->clone(robot->getName());
207 }
208
209 // IceUtil::Time start = IceUtil::Time::now();
210 // ARMARX_INFO << jointVel; FramedPoseBaseMap tcpPoses;
211 FramedDirectionMap tcpTranslationVelocities;
212 FramedDirectionMap tcpOrientationVelocities;
213 std::string rootFrame = robot->getRootNode()->getName();
214 NameValueMap tempJointAngles = robot->getConfig()->getRobotNodeJointValueMap();
215 FramedPoseBaseMap tcpPoses;
216
217 for (unsigned int i = 0; i < nodesToReport.size(); i++)
218 {
219 RobotNodePtr node = nodesToReport.at(i).first;
220 const std::string& tcpName = node->getName();
221 const Eigen::Matrix4f& currentPose =
222 velocityReportRobot->getRobotNode(tcpName)->getGlobalPose();
223 tcpPoses[tcpName] = new FramedPose(currentPose, GlobalFrame, "");
224 }
225
226
227 velocityReportRobot->setJointValues(tempJointAngles);
228 velocityReportRobot->setGlobalPose(robot->getGlobalPose());
229
230 Eigen::Matrix4f mat;
231 Eigen::Vector3f rpy;
232
233 auto keys = armarx::getMapKeys(jointVel);
234 Eigen::VectorXf jointVelocities(jointVel.size());
235 auto rootFrameName = velocityReportRobot->getRootNode()->getName();
236 RobotNodeSetPtr rns =
237 RobotNodeSet::createRobotNodeSet(velocityReportRobot, "All_Nodes", keys, rootFrameName);
238 for (size_t i = 0; i < rns->getSize(); ++i)
239 {
240 jointVelocities(i) = jointVel.at(rns->getNode(i)->getName());
241 }
242 DifferentialIKPtr j(new DifferentialIK(rns));
243
244
245 auto robotName = velocityReportRobot->getName();
246 for (unsigned int i = 0; i < nodesToReport.size(); i++)
247 {
248 RobotNodePtr node = velocityReportRobot->getRobotNode(nodesToReport.at(i).first->getName());
249 Eigen::MatrixXf jac = j->getJacobianMatrix(node, IKSolver::All);
250 Eigen::VectorXf nodeVel = jac * jointVelocities;
251
252 const std::string tcpName = node->getName();
253 tcpTranslationVelocities[tcpName] =
254 new FramedDirection(nodeVel.block<3, 1>(0, 0), rootFrameName, robotName);
255 tcpOrientationVelocities[tcpName] =
256 new FramedDirection(nodeVel.block<3, 1>(3, 0), rootFrameName, robotName);
257 }
258 updateVelocityDatafields(tcpTranslationVelocities, tcpOrientationVelocities);
259}
260
261void
262RobotStateObserver::updateVelocityDatafields(const FramedDirectionMap& tcpTranslationVelocities,
263 const FramedDirectionMap& tcpOrientationVelocities)
264{
265 FramedDirectionMap::const_iterator it = tcpTranslationVelocities.begin();
266
267 for (; it != tcpTranslationVelocities.end(); it++)
268 {
269
270 FramedDirectionPtr vec = FramedDirectionPtr::dynamicCast(it->second);
271 FramedDirectionPtr vecOri;
272 FramedDirectionMap::const_iterator itOri = tcpOrientationVelocities.find(it->first);
273
274 if (itOri != tcpOrientationVelocities.end())
275 {
276 vecOri = FramedDirectionPtr::dynamicCast(itOri->second);
277 }
278
279 const std::string& tcpName = it->first;
280
281 ARMARX_CHECK_EXPRESSION(vec->frame == vecOri->frame);
282
284 {
286 TCP_TRANS_VELOCITIES_CHANNEL, tcpName, Variant(it->second), "Pose of " + tcpName);
287 }
288 else
289 {
291 }
292
294 const std::string channelName = tcpName + "Velocities";
295
296 if (!existsChannel(channelName))
297 {
298 offerChannel(channelName, "pose components of " + tcpName);
299 offerDataFieldWithDefault(channelName, "x", Variant(vec->x), "X axis");
300 offerDataFieldWithDefault(channelName, "y", Variant(vec->y), "Y axis");
301 offerDataFieldWithDefault(channelName, "z", Variant(vec->z), "Z axis");
302 offerDataFieldWithDefault(channelName, "roll", Variant(vecOri->x), "Roll");
303 offerDataFieldWithDefault(channelName, "pitch", Variant(vecOri->y), "Pitch");
304 offerDataFieldWithDefault(channelName, "yaw", Variant(vecOri->z), "Yaw");
306 channelName, "frame", Variant(vecOri->frame), "Reference Frame");
307 }
308 else
309 {
310 StringVariantBaseMap newValues;
311 newValues["x"] = new Variant(vec->x);
312 newValues["y"] = new Variant(vec->y);
313 newValues["z"] = new Variant(vec->z);
314 newValues["roll"] = new Variant(vecOri->x);
315 newValues["pitch"] = new Variant(vecOri->y);
316 newValues["yaw"] = new Variant(vecOri->z);
317 newValues["frame"] = new Variant(vec->frame);
318 setDataFieldsFlatCopy(channelName, newValues);
319 }
320
321 updateChannel(channelName);
322 }
323}
324
330
331void
333{
334 std::unique_lock lock(dataMutex);
335 this->robot = robot;
336
337 std::vector<VirtualRobot::RobotNodeSetPtr> robotNodes;
338 robotNodes = robot->getRobotNodeSets();
339
340 std::string nodesetsString = getProperty<std::string>("TCPsToReport").getValue();
341 nodesToReport.clear();
342 // nodesToReport.push_back(std::make_pair(robot->getRootNode(), GlobalFrame));
343 if (!nodesetsString.empty())
344 {
345 if (nodesetsString == "*")
346 {
347 auto nodesets = robot->getRobotNodeSets();
348
349 for (RobotNodeSetPtr& set : nodesets)
350 {
351 if (set->getTCP())
352 {
353 nodesToReport.push_back(
354 std::make_pair(set->getTCP(), robot->getRootNode()->getName()));
355 }
356 }
357 }
358 else
359 {
360 std::vector<std::string> nodesetNames = simox::alg::split(nodesetsString, ",");
361
362 for (auto name : nodesetNames)
363 {
364 simox::alg::trim(name);
365 auto node = robot->getRobotNode(name);
366
367 if (node)
368 {
369 nodesToReport.push_back(std::make_pair(node, robot->getRootNode()->getName()));
370 }
371 else
372 {
373 ARMARX_ERROR << "Could not find node with name: " << name;
374 }
375 }
376 }
377 }
378}
#define TCP_POSE_CHANNEL
#define TCP_TRANS_VELOCITIES_CHANNEL
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition Component.cpp:90
Property< PropertyType > getProperty(const std::string &name)
Checks if the numbers published in the relevant data fields equal a reference value.
Checks if the numbers published in the relevant data fields are within a reference range.
Checks if the numbers published in the relevant data fields are larger than a reference value.
Checks if the numbers published in the relevant data fields are smaller than a reference value.
FramedDirection is a 3 dimensional direction vector with a reference frame.
Definition FramedPose.h:87
The FramedPose class.
Definition FramedPose.h:281
int getState() const
Retrieve current state of the ManagedIceObject.
bool existsChannel(const std::string &channelName) const
void offerChannel(std::string channelName, std::string description)
Offer a channel.
Definition Observer.cpp:131
void offerConditionCheck(std::string checkName, ConditionCheck *conditionCheck)
Offer a condition check.
Definition Observer.cpp:301
void updateChannel(const std::string &channelName, const std::set< std::string > &updatedDatafields=std::set< std::string >())
Update all conditions for a channel.
Definition Observer.cpp:788
void addWorkerJob(const std::string &name, std::function< void(void)> &&f) const
void setDataFieldsFlatCopy(const std::string &channelName, const StringVariantBaseMap &datafieldValues, bool triggerFilterUpdate=true)
Definition Observer.cpp:728
void offerDataFieldWithDefault(std::string channelName, std::string datafieldName, const Variant &defaultValue, std::string description)
Offer a datafield with default value.
Definition Observer.cpp:160
bool existsDataField(const std::string &channelName, const std::string &datafieldName) const
DatafieldRefBasePtr getDatafieldRefByName(const std::string &channelName, const std::string &datafieldName) const
void setDataField(const std::string &channelName, const std::string &datafieldName, const Variant &value, bool triggerFilterUpdate=true)
set datafield with datafieldName and in channel channelName
Definition Observer.cpp:508
RobotStatePropertyDefinition Property Definitions.
void onConnectObserver() override
Framework hook.
void udpatePoseDatafields(const FramedPoseBaseMap &poseMap)
void updateVelocityDatafields(const FramedDirectionMap &tcpTranslationVelocities, const FramedDirectionMap &tcpOrientationVelocities)
void getPoseDatafield_async(const AMD_RobotStateObserverInterface_getPoseDatafieldPtr &amd, const std::string &nodeName, const Ice::Current &) const override
PropertyDefinitionsPtr createPropertyDefinitions() override
void onInitObserver() override
Framework hook.
void updateNodeVelocities(const NameValueMap &jointVel, long timestampMicroSeconds)
void setRobot(VirtualRobot::RobotPtr robot)
The Variant class is described here: Variants.
Definition Variant.h:224
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
std::string const GlobalFrame
Variable of the global coordinate system.
Definition FramedPose.h:65
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::map< std::string, VariantBasePtr > StringVariantBaseMap
IceInternal::Handle< FramedDirection > FramedDirectionPtr
Definition FramedPose.h:84
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
void getMapKeys(const MapType &map, OutputIteratorType it)
Definition algorithm.h:173
IceInternal::Handle< FramedPose > FramedPosePtr
Definition FramedPose.h:272
::std::map<::std::string, ::armarx::FramedPoseBasePtr > FramedPoseBaseMap