KinematicUnitObserver.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 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
24
25#include <SimoxUtility/algorithm/string/string_tools.h>
26#include <VirtualRobot/Nodes/RobotNode.h>
27#include <VirtualRobot/RobotNodeSet.h>
28#include <VirtualRobot/VirtualRobot.h>
29#include <VirtualRobot/XML/RobotIO.h>
30
41
42#include "KinematicUnit.h"
43
44namespace armarx
45{
46 // ********************************************************************
47 // observer framework hooks
48 // ********************************************************************
49 void
51 {
52 robotNodeSetName = getProperty<std::string>("RobotNodeSetName").getValue();
53
54 // register all checks
62
63 usingTopic(getProperty<std::string>("TopicPrefix").getValue() + robotNodeSetName + "State");
64 }
65
66 void
68 {
69 // read names of kinematic chain elements belonging to this unit from XML and setup a map of all joints
70 // the kinematic chain elements belonging to this unit are defined in a RobotNodeSet
71 std::string robotFile = getProperty<std::string>("RobotFileName").getValue();
72 std::string project = getProperty<std::string>("RobotFileNameProject").getValue();
73 Ice::StringSeq includePaths;
74
75 if (!project.empty())
76 {
77 CMakePackageFinder finder(project);
78
79 auto pathsString = finder.getDataDir();
80 Ice::StringSeq projectIncludePaths = simox::alg::split(pathsString, ";,");
81 includePaths.insert(
82 includePaths.end(), projectIncludePaths.begin(), projectIncludePaths.end());
83 }
84
85 if (!ArmarXDataPath::getAbsolutePath(robotFile, robotFile, includePaths))
86 {
87 throw UserException("Could not find robot file " + robotFile);
88 }
89
91 VirtualRobot::RobotIO::loadRobot(robotFile, VirtualRobot::RobotIO::eStructure);
92
93 if (robotNodeSetName == "")
94 {
95 throw UserException("RobotNodeSet not defined");
96 }
97
98 auto robotNodeSetPtr = robot->getRobotNodeSet(robotNodeSetName);
99
100 std::vector<VirtualRobot::RobotNodePtr> robotNodes;
101 robotNodes = robotNodeSetPtr->getAllRobotNodes();
102 auto robotNodeNames = robotNodeSetPtr->getNodeNames();
103 this->robotNodes = std::set<std::string>(robotNodeNames.begin(), robotNodeNames.end());
104 // register all channels
105 offerChannel("jointangles", "Joint values of the " + robotNodeSetName + " kinematic chain");
106 offerChannel("jointvelocities",
107 "Joint velocities of the " + robotNodeSetName + " kinematic chain");
108 offerChannel("jointaccelerations",
109 "Joint accelerations of the " + robotNodeSetName + " kinematic chain");
110 offerChannel("jointtorques",
111 "Joint torques of the" + robotNodeSetName + " kinematic chain");
112 offerChannel("jointcurrents",
113 "Joint currents of the " + robotNodeSetName + " kinematic chain");
114 offerChannel("jointmotortemperatures",
115 "Joint motor temperatures of the " + robotNodeSetName + " kinematic chain");
116 offerChannel("jointcontrolmodes",
117 "Joint motor temperatures of the " + robotNodeSetName + " kinematic chain");
118
119
120 // register all data fields
121 for (std::vector<VirtualRobot::RobotNodePtr>::iterator it = robotNodes.begin();
122 it != robotNodes.end();
123 it++)
124 {
125 std::string jointName = (*it)->getName();
126 ARMARX_VERBOSE << "* " << jointName << std::endl;
127 offerDataFieldWithDefault("jointcontrolmodes",
128 jointName,
129 ControlModeToString(eUnknown),
130 "Controlmode of the " + jointName + " joint");
131 offerDataField("jointangles",
132 jointName,
134 "Joint angle of the " + jointName + " joint in radians");
135 offerDataField("jointvelocities",
136 jointName,
138 "Joint velocity of the " + jointName + " joint");
139 offerDataField("jointaccelerations",
140 jointName,
142 "Joint acceleration of the " + jointName + " joint");
143 offerDataField("jointtorques",
144 jointName,
146 "Joint torque of the " + jointName + " joint");
147 offerDataField("jointcurrents",
148 jointName,
150 "Joint current of the " + jointName + " joint");
151 offerDataField("jointmotortemperatures",
152 jointName,
154 "Joint motor temperature of the " + jointName + " joint");
155 }
156
157 updateChannel("jointcontrolmodes");
158 }
159
160 // ********************************************************************
161 // KinematicUnitListener interface implementation
162 // ********************************************************************
163 void
164 KinematicUnitObserver::reportControlModeChanged(const NameControlModeMap& jointModes,
165 Ice::Long timestamp,
166 bool aValueChanged,
167 const Ice::Current& c)
168 {
169 try
170 {
171 if (jointModes.size() == 0)
172 {
173 return;
174 }
175
176 for (auto elem : jointModes)
177 {
179 "jointcontrolmodes", elem.first, new Variant(ControlModeToString(elem.second)));
180 }
181
182 updateChannel("jointcontrolmodes");
183 }
184 catch (...)
185 {
187 }
188 }
189
190 void
191 KinematicUnitObserver::reportJointAngles(const NameValueMap& jointAngles,
192 Ice::Long timestamp,
193 bool aValueChanged,
194 const Ice::Current& c)
195 {
196 try
197 {
198
199
200 if (jointAngles.size() == 0)
201 {
202 return;
203 }
204
205 nameValueMapToDataFields("jointangles", jointAngles, timestamp, aValueChanged);
206
207
208 updateChannel("jointangles");
209 }
210 catch (...)
211 {
213 }
214 }
215
216 void
217 KinematicUnitObserver::reportJointVelocities(const NameValueMap& jointVelocities,
218 Ice::Long timestamp,
219 bool aValueChanged,
220 const Ice::Current& c)
221 {
222 try
223 {
224 if (jointVelocities.size() == 0)
225 {
226 return;
227 }
228
229
230 nameValueMapToDataFields("jointvelocities", jointVelocities, timestamp, aValueChanged);
231
232 updateChannel("jointvelocities");
233 }
234 catch (...)
235 {
237 }
238 }
239
240 void
241 KinematicUnitObserver::reportJointTorques(const NameValueMap& jointTorques,
242 Ice::Long timestamp,
243 bool aValueChanged,
244 const Ice::Current& c)
245 {
246 try
247 {
248 if (jointTorques.size() == 0)
249 {
250 return;
251 }
252
253
254 nameValueMapToDataFields("jointtorques", jointTorques, timestamp, aValueChanged);
255
256 updateChannel("jointtorques");
257 }
258 catch (...)
259 {
261 }
262 }
263
264 void
265 KinematicUnitObserver::reportJointAccelerations(const NameValueMap& jointAccelerations,
266 Ice::Long timestamp,
267 bool aValueChanged,
268 const Ice::Current& c)
269 {
270 try
271 {
272 if (jointAccelerations.size() == 0)
273 {
274 return;
275 }
276
277
279 "jointaccelerations", jointAccelerations, timestamp, aValueChanged);
280
281 updateChannel("jointaccelerations");
282 }
283 catch (...)
284 {
286 }
287 }
288
289 void
290 KinematicUnitObserver::reportJointCurrents(const NameValueMap& jointCurrents,
291 Ice::Long timestamp,
292 bool aValueChanged,
293 const Ice::Current& c)
294 {
295 try
296 {
297 if (jointCurrents.size() == 0)
298 {
299 return;
300 }
301
302
303 nameValueMapToDataFields("jointcurrents", jointCurrents, timestamp, aValueChanged);
304
305 updateChannel("jointcurrents");
306 }
307 catch (...)
308 {
310 }
311 }
312
313 void
314 KinematicUnitObserver::reportJointMotorTemperatures(const NameValueMap& jointMotorTemperatures,
315 Ice::Long timestamp,
316 bool aValueChanged,
317 const Ice::Current& c)
318 {
319 try
320 {
321 if (jointMotorTemperatures.size() == 0)
322 {
323 return;
324 }
325
326
328 "jointmotortemperatures", jointMotorTemperatures, timestamp, aValueChanged);
329
330 updateChannel("jointmotortemperatures");
331 }
332 catch (...)
333 {
335 }
336 }
337
338 void
339 KinematicUnitObserver::reportJointStatuses(const NameStatusMap& jointStatuses,
340 Ice::Long timestamp,
341 bool aValueChanged,
342 const Ice::Current& c)
343 {
344 }
345
346 // ********************************************************************
347 // private methods
348 // ********************************************************************
349 void
351 const NameValueMap& nameValueMap,
352 Ice::Long timestamp,
353 bool aValueChanged)
354 {
355 // ARMARX_INFO << deactivateSpam(10) << " timestamp is " << (IceUtil::Time::now() - IceUtil::Time::microSeconds(timestamp)).toMicroSecondsDouble() << " µs old";
356 bool newChannel;
357 {
358 std::unique_lock lock(initializedChannelsMutex);
359 newChannel = initializedChannels.count(channelName) == 0;
360 initializedChannels.insert(channelName);
361 }
362 if (aValueChanged || newChannel)
363 {
364
365 std::unordered_map<::std::string, ::armarx::VariantBasePtr> map;
366 if (timestamp < 0)
367 {
368 for (const auto& it : nameValueMap)
369 {
370 if (robotNodes.count(it.first))
371 {
372 map[it.first] = new Variant(it.second);
373 }
374 }
375 }
376 else
377 {
378 for (const auto& it : nameValueMap)
379 {
380 if (robotNodes.count(it.first))
381 {
382 map[it.first] = new TimedVariant(new Variant(it.second),
383 IceUtil::Time::microSeconds(timestamp));
384 }
385 }
386 }
387 setDataFieldsFlatCopy(channelName, map);
388 }
389 else
390 {
392 }
393 }
394
401} // namespace armarx
std::string timestamp()
constexpr T c
static bool getAbsolutePath(const std::string &relativeFilename, std::string &storeAbsoluteFilename, const std::vector< std::string > &additionalSearchPaths={}, bool verbose=true)
The CMakePackageFinder class provides an interface to the CMake Package finder capabilities.
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 reference value with respect to a t...
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.
Checks if the relevant data fields have been updated since the installation of this condition.
Checks if the relevant data fields contain valid values.
void reportJointMotorTemperatures(const NameValueMap &jointMotorTemperatures, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
void onConnectObserver() override
Framework hook.
void reportJointVelocities(const NameValueMap &jointVelocities, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
void reportJointAngles(const NameValueMap &jointAngles, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
void reportJointTorques(const NameValueMap &jointTorques, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
void reportControlModeChanged(const NameControlModeMap &jointModes, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
void reportJointCurrents(const NameValueMap &jointCurrents, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
void nameValueMapToDataFields(const std::string &channelName, const NameValueMap &nameValueMap, Ice::Long timestamp, bool aValueChanged)
void reportJointAccelerations(const NameValueMap &jointAccelerations, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c) override
void reportJointStatuses(const NameStatusMap &jointStatuses, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
PropertyDefinitionsPtr createPropertyDefinitions() override
void onInitObserver() override
Framework hook.
static std::string ControlModeToString(ControlMode mode)
std::set< std::string > initializedChannels
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
void offerChannel(std::string channelName, std::string description)
Offer a channel.
Definition Observer.cpp:131
void offerDataField(std::string channelName, std::string datafieldName, VariantTypeId type, std::string description)
Offer a datafield without default value.
Definition Observer.cpp:201
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 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
void updateDatafieldTimestamps(const std::string &channelName, const std::unordered_map< std::string, Ice::Long > &datafieldValues)
Definition Observer.cpp:580
void setDataFieldFlatCopy(const std::string &channelName, const std::string &datafieldName, const VariantPtr &value, bool triggerFilterUpdate=true)
Definition Observer.cpp:548
The Variant class is described here: Variants.
Definition Variant.h:224
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
const VariantTypeId Float
Definition Variant.h:919
This file offers overloads of toIce() and fromIce() functions for STL container types.
void handleExceptions()
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.