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 
23 #include "KinematicUnitObserver.h"
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 
44 namespace 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  {
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,
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
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
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
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
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
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
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,
341  bool aValueChanged,
342  const Ice::Current& c)
343  {
344  }
345 
346  // ********************************************************************
347  // private methods
348  // ********************************************************************
349  void
350  KinematicUnitObserver::nameValueMapToDataFields(const std::string& channelName,
351  const NameValueMap& nameValueMap,
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  {
391  updateDatafieldTimestamps(channelName, timestamp);
392  }
393  }
394 
397  {
398  return PropertyDefinitionsPtr(
400  }
401 } // namespace armarx
armarx::Observer::updateChannel
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
armarx::KinematicUnitObserver::reportControlModeChanged
void reportControlModeChanged(const NameControlModeMap &jointModes, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitObserver.cpp:164
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:223
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:919
armarx::KinematicUnitObserver::reportJointMotorTemperatures
void reportJointMotorTemperatures(const NameValueMap &jointMotorTemperatures, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitObserver.cpp:314
armarx::KinematicUnitObserverPropertyDefinitions
Definition: KinematicUnitObserver.h:43
ConditionCheckEquals.h
ConditionCheckInRange.h
armarx::KinematicUnitObserver::onInitObserver
void onInitObserver() override
Framework hook.
Definition: KinematicUnitObserver.cpp:50
armarx::CMakePackageFinder
The CMakePackageFinder class provides an interface to the CMake Package finder capabilities.
Definition: CMakePackageFinder.h:52
armarx::ConditionCheckSmaller
Definition: ConditionCheckSmaller.h:40
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
KinematicUnit.h
armarx::Observer::setDataFieldsFlatCopy
void setDataFieldsFlatCopy(const std::string &channelName, const StringVariantBaseMap &datafieldValues, bool triggerFilterUpdate=true)
Definition: Observer.cpp:728
project
std::string project
Definition: VisualizationRobot.cpp:85
armarx::Observer::updateDatafieldTimestamps
void updateDatafieldTimestamps(const std::string &channelName, const std::unordered_map< std::string, Ice::Long > &datafieldValues)
Definition: Observer.cpp:580
armarx::KinematicUnitObserver::reportJointStatuses
void reportJointStatuses(const NameStatusMap &jointStatuses, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitObserver.cpp:339
armarx::KinematicUnitObserver::onConnectObserver
void onConnectObserver() override
Framework hook.
Definition: KinematicUnitObserver.cpp:67
armarx::ConditionCheckUpdated
Definition: ConditionCheckUpdated.h:41
armarx::KinematicUnitObserver::ControlModeToString
static std::string ControlModeToString(ControlMode mode)
Definition: KinematicUnitObserver.h:132
armarx::Observer::setDataFieldFlatCopy
void setDataFieldFlatCopy(const std::string &channelName, const std::string &datafieldName, const VariantPtr &value, bool triggerFilterUpdate=true)
Definition: Observer.cpp:548
armarx::CMakePackageFinder::getDataDir
std::string getDataDir() const
Definition: CMakePackageFinder.h:194
armarx::VariantType::Long
const VariantTypeId Long
Definition: Variant.h:918
armarx::ConditionCheckEqualsWithTolerance
Definition: ConditionCheckEqualsWithTolerance.h:41
timestamp
std::string timestamp()
Definition: CartographerAdapter.cpp:85
armarx::channels::KinematicUnitObserver::jointVelocities
const KinematicUnitDatafieldCreator jointVelocities("jointVelocities")
armarx::KinematicUnitObserver::nameValueMapToDataFields
void nameValueMapToDataFields(const std::string &channelName, const NameValueMap &nameValueMap, Ice::Long timestamp, bool aValueChanged)
Definition: KinematicUnitObserver.cpp:350
ConditionCheckEqualsWithTolerance.h
armarx::KinematicUnitObserver::reportJointAccelerations
void reportJointAccelerations(const NameValueMap &jointAccelerations, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c) override
Definition: KinematicUnitObserver.cpp:265
armarx::ConditionCheckInRange
Definition: ConditionCheckInRange.h:41
armarx::KinematicUnitObserver::initializedChannelsMutex
std::mutex initializedChannelsMutex
Definition: KinematicUnitObserver.h:194
armarx::control::njoint_controller::platform::platform_follower_controller::NameValueMap
std::map< std::string, float > NameValueMap
Definition: PlatformFollowerController.h:88
armarx::channels::KinematicUnitObserver::jointAngles
const KinematicUnitDatafieldCreator jointAngles("jointAngles")
armarx::ManagedIceObject::usingTopic
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
Definition: ManagedIceObject.cpp:254
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:79
armarx::channels::KinematicUnitObserver::jointCurrents
const KinematicUnitDatafieldCreator jointCurrents("jointCurrents")
CMakePackageFinder.h
armarx::KinematicUnitObserver::reportJointCurrents
void reportJointCurrents(const NameValueMap &jointCurrents, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitObserver.cpp:290
armarx::KinematicUnitObserver::createPropertyDefinitions
PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: KinematicUnitObserver.cpp:396
ConditionCheckSmaller.h
IceUtil::Handle
Definition: forward_declarations.h:30
armarx::ConditionCheckEquals
Definition: ConditionCheckEquals.h:46
armarx::Observer::offerConditionCheck
void offerConditionCheck(std::string checkName, ConditionCheck *conditionCheck)
Offer a condition check.
Definition: Observer.cpp:301
armarx::ArmarXDataPath::getAbsolutePath
static bool getAbsolutePath(const std::string &relativeFilename, std::string &storeAbsoluteFilename, const std::vector< std::string > &additionalSearchPaths={}, bool verbose=true)
Definition: ArmarXDataPath.cpp:109
ConditionCheckLarger.h
armarx::ConditionCheckLarger
Definition: ConditionCheckLarger.h:40
armarx::Observer::offerDataFieldWithDefault
void offerDataFieldWithDefault(std::string channelName, std::string datafieldName, const Variant &defaultValue, std::string description)
Offer a datafield with default value.
Definition: Observer.cpp:160
armarx::handleExceptions
void handleExceptions()
Definition: Exception.cpp:157
armarx::channels::KinematicUnitObserver::jointTorques
const KinematicUnitDatafieldCreator jointTorques("jointTorques")
armarx::KinematicUnitObserver::reportJointVelocities
void reportJointVelocities(const NameValueMap &jointVelocities, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitObserver.cpp:217
armarx::PropertyDefinitionsPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Definition: forward_declarations.h:35
armarx::KinematicUnitObserver::reportJointTorques
void reportJointTorques(const NameValueMap &jointTorques, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitObserver.cpp:241
armarx::Observer::offerDataField
void offerDataField(std::string channelName, std::string datafieldName, VariantTypeId type, std::string description)
Offer a datafield without default value.
Definition: Observer.cpp:201
ArmarXDataPath.h
ConditionCheckValid.h
armarx::ConditionCheckValid
Definition: ConditionCheckValid.h:40
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
KinematicUnitObserver.h
armarx::KinematicUnitObserver::reportJointAngles
void reportJointAngles(const NameValueMap &jointAngles, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitObserver.cpp:191
armarx::TimedVariant
Definition: TimedVariant.h:39
ChannelRef.h
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:19
armarx::KinematicUnitObserver::initializedChannels
std::set< std::string > initializedChannels
Definition: KinematicUnitObserver.h:193
armarx::split
std::vector< std::string > split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelpers.cpp:38
ConditionCheckUpdated.h
armarx::Observer::offerChannel
void offerChannel(std::string channelName, std::string description)
Offer a channel.
Definition: Observer.cpp:131