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 #include "KinematicUnit.h"
34 
35 #include <VirtualRobot/VirtualRobot.h>
36 #include <VirtualRobot/XML/RobotIO.h>
37 #include <VirtualRobot/RobotNodeSet.h>
38 #include <VirtualRobot/Nodes/RobotNode.h>
40 
41 #include <SimoxUtility/algorithm/string/string_tools.h>
42 
43 namespace armarx
44 {
45  // ********************************************************************
46  // observer framework hooks
47  // ********************************************************************
49  {
50  robotNodeSetName = getProperty<std::string>("RobotNodeSetName").getValue();
51 
52  // register all checks
60 
61  usingTopic(getProperty<std::string>("TopicPrefix").getValue() + robotNodeSetName + "State");
62  }
63 
65  {
66  // read names of kinematic chain elements belonging to this unit from XML and setup a map of all joints
67  // the kinematic chain elements belonging to this unit are defined in a RobotNodeSet
68  std::string robotFile = getProperty<std::string>("RobotFileName").getValue();
69  std::string project = getProperty<std::string>("RobotFileNameProject").getValue();
70  Ice::StringSeq includePaths;
71 
72  if (!project.empty())
73  {
75 
76  auto pathsString = finder.getDataDir();
77  Ice::StringSeq projectIncludePaths = simox::alg::split(pathsString, ";,");
78  includePaths.insert(includePaths.end(), projectIncludePaths.begin(), projectIncludePaths.end());
79  }
80 
81  if (!ArmarXDataPath::getAbsolutePath(robotFile, robotFile, includePaths))
82  {
83  throw UserException("Could not find robot file " + robotFile);
84  }
85 
86  VirtualRobot::RobotPtr robot = VirtualRobot::RobotIO::loadRobot(robotFile, VirtualRobot::RobotIO::eStructure);
87 
88  if (robotNodeSetName == "")
89  {
90  throw UserException("RobotNodeSet not defined");
91  }
92 
93  auto robotNodeSetPtr = robot->getRobotNodeSet(robotNodeSetName);
94 
95  std::vector< VirtualRobot::RobotNodePtr > robotNodes;
96  robotNodes = robotNodeSetPtr->getAllRobotNodes();
97  auto robotNodeNames = robotNodeSetPtr->getNodeNames();
98  this->robotNodes = std::set<std::string>(robotNodeNames.begin(), robotNodeNames.end());
99  // register all channels
100  offerChannel("jointangles", "Joint values of the " + robotNodeSetName + " kinematic chain");
101  offerChannel("jointvelocities", "Joint velocities of the " + robotNodeSetName + " kinematic chain");
102  offerChannel("jointaccelerations", "Joint accelerations of the " + robotNodeSetName + " kinematic chain");
103  offerChannel("jointtorques", "Joint torques of the" + robotNodeSetName + " kinematic chain");
104  offerChannel("jointcurrents", "Joint currents of the " + robotNodeSetName + " kinematic chain");
105  offerChannel("jointmotortemperatures", "Joint motor temperatures of the " + robotNodeSetName + " kinematic chain");
106  offerChannel("jointcontrolmodes", "Joint motor temperatures of the " + robotNodeSetName + " kinematic chain");
107 
108 
109  // register all data fields
110  for (std::vector<VirtualRobot::RobotNodePtr>::iterator it = robotNodes.begin(); it != robotNodes.end(); it++)
111  {
112  std::string jointName = (*it)->getName();
113  ARMARX_VERBOSE << "* " << jointName << std::endl;
114  offerDataFieldWithDefault("jointcontrolmodes", jointName, ControlModeToString(eUnknown), "Controlmode of the " + jointName + " joint");
115  offerDataField("jointangles", jointName, VariantType::Float, "Joint angle of the " + jointName + " joint in radians");
116  offerDataField("jointvelocities", jointName, VariantType::Float, "Joint velocity of the " + jointName + " joint");
117  offerDataField("jointaccelerations", jointName, VariantType::Float, "Joint acceleration of the " + jointName + " joint");
118  offerDataField("jointtorques", jointName, VariantType::Float, "Joint torque of the " + jointName + " joint");
119  offerDataField("jointcurrents", jointName, VariantType::Float, "Joint current of the " + jointName + " joint");
120  offerDataField("jointmotortemperatures", jointName, VariantType::Float, "Joint motor temperature of the " + jointName + " joint");
121  }
122 
123  updateChannel("jointcontrolmodes");
124  }
125 
126 
127 
128  // ********************************************************************
129  // KinematicUnitListener interface implementation
130  // ********************************************************************
131  void KinematicUnitObserver::reportControlModeChanged(const NameControlModeMap& jointModes, Ice::Long timestamp, bool aValueChanged, const Ice::Current& c)
132  {
133  try
134  {
135  if (jointModes.size() == 0)
136  {
137  return;
138  }
139 
140  for (auto elem : jointModes)
141  {
142  setDataFieldFlatCopy("jointcontrolmodes", elem.first, new Variant(ControlModeToString(elem.second)));
143  }
144 
145  updateChannel("jointcontrolmodes");
146  }
147  catch (...)
148  {
150  }
151  }
152 
153  void KinematicUnitObserver::reportJointAngles(const NameValueMap& jointAngles, Ice::Long timestamp, bool aValueChanged, const Ice::Current& c)
154  {
155  try
156  {
157 
158 
159  if (jointAngles.size() == 0)
160  {
161  return;
162  }
163 
164  nameValueMapToDataFields("jointangles", jointAngles, timestamp, aValueChanged);
165 
166 
167  updateChannel("jointangles");
168 
169  }
170  catch (...)
171  {
173  }
174  }
175 
176 
177  void KinematicUnitObserver::reportJointVelocities(const NameValueMap& jointVelocities, Ice::Long timestamp, bool aValueChanged, const Ice::Current& c)
178  {
179  try
180  {
181  if (jointVelocities.size() == 0)
182  {
183  return;
184  }
185 
186 
187  nameValueMapToDataFields("jointvelocities", jointVelocities, timestamp, aValueChanged);
188 
189  updateChannel("jointvelocities");
190  }
191  catch (...)
192  {
194  }
195  }
196 
197  void KinematicUnitObserver::reportJointTorques(const NameValueMap& jointTorques, Ice::Long timestamp, bool aValueChanged, const Ice::Current& c)
198  {
199  try
200  {
201  if (jointTorques.size() == 0)
202  {
203  return;
204  }
205 
206 
207  nameValueMapToDataFields("jointtorques", jointTorques, timestamp, aValueChanged);
208 
209  updateChannel("jointtorques");
210  }
211  catch (...)
212  {
214  }
215  }
216 
217  void KinematicUnitObserver::reportJointAccelerations(const NameValueMap& jointAccelerations, Ice::Long timestamp, bool aValueChanged, const Ice::Current& c)
218  {
219  try
220  {
221  if (jointAccelerations.size() == 0)
222  {
223  return;
224  }
225 
226 
227  nameValueMapToDataFields("jointaccelerations", jointAccelerations, timestamp, aValueChanged);
228 
229  updateChannel("jointaccelerations");
230  }
231  catch (...)
232  {
234  }
235  }
236 
237  void KinematicUnitObserver::reportJointCurrents(const NameValueMap& jointCurrents, Ice::Long timestamp, bool aValueChanged, const Ice::Current& c)
238  {
239  try
240  {
241  if (jointCurrents.size() == 0)
242  {
243  return;
244  }
245 
246 
247  nameValueMapToDataFields("jointcurrents", jointCurrents, timestamp, aValueChanged);
248 
249  updateChannel("jointcurrents");
250  }
251  catch (...)
252  {
254  }
255  }
256 
257  void KinematicUnitObserver::reportJointMotorTemperatures(const NameValueMap& jointMotorTemperatures, Ice::Long timestamp, bool aValueChanged, const Ice::Current& c)
258  {
259  try
260  {
261  if (jointMotorTemperatures.size() == 0)
262  {
263  return;
264  }
265 
266 
267  nameValueMapToDataFields("jointmotortemperatures", jointMotorTemperatures, timestamp, aValueChanged);
268 
269  updateChannel("jointmotortemperatures");
270  }
271  catch (...)
272  {
274  }
275  }
276 
277  void KinematicUnitObserver::reportJointStatuses(const NameStatusMap& jointStatuses, Ice::Long timestamp, bool aValueChanged, const Ice::Current& c)
278  {
279  }
280 
281  // ********************************************************************
282  // private methods
283  // ********************************************************************
284  void KinematicUnitObserver::nameValueMapToDataFields(const std::string& channelName, const NameValueMap& nameValueMap, Ice::Long timestamp, bool aValueChanged)
285  {
286  // ARMARX_INFO << deactivateSpam(10) << " timestamp is " << (IceUtil::Time::now() - IceUtil::Time::microSeconds(timestamp)).toMicroSecondsDouble() << " µs old";
287  bool newChannel;
288  {
289  std::unique_lock lock(initializedChannelsMutex);
290  newChannel = initializedChannels.count(channelName) == 0;
291  initializedChannels.insert(channelName);
292  }
293  if (aValueChanged || newChannel)
294  {
295 
296  std::unordered_map< ::std::string, ::armarx::VariantBasePtr> map;
297  if (timestamp < 0)
298  {
299  for (const auto& it : nameValueMap)
300  {
301  if (robotNodes.count(it.first))
302  {
303  map[it.first] = new Variant(it.second);
304  }
305  }
306  }
307  else
308  {
309  for (const auto& it : nameValueMap)
310  {
311  if (robotNodes.count(it.first))
312  {
313  map[it.first] = new TimedVariant(new Variant(it.second), IceUtil::Time::microSeconds(timestamp));
314  }
315  }
316  }
317  setDataFieldsFlatCopy(channelName, map);
318  }
319  else
320  {
321  updateDatafieldTimestamps(channelName, timestamp);
322  }
323 
324  }
325 
327  {
330  }
331 }
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:715
armarx::KinematicUnitObserver::reportControlModeChanged
void reportControlModeChanged(const NameControlModeMap &jointModes, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitObserver.cpp:131
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:224
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:918
armarx::KinematicUnitObserver::reportJointMotorTemperatures
void reportJointMotorTemperatures(const NameValueMap &jointMotorTemperatures, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitObserver.cpp:257
armarx::KinematicUnitObserverPropertyDefinitions
Definition: KinematicUnitObserver.h:42
ConditionCheckEquals.h
ConditionCheckInRange.h
armarx::KinematicUnitObserver::onInitObserver
void onInitObserver() override
Framework hook.
Definition: KinematicUnitObserver.cpp:48
armarx::CMakePackageFinder
The CMakePackageFinder class provides an interface to the CMake Package finder capabilities.
Definition: CMakePackageFinder.h:53
armarx::ConditionCheckSmaller
Definition: ConditionCheckSmaller.h:40
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
KinematicUnit.h
armarx::Observer::setDataFieldsFlatCopy
void setDataFieldsFlatCopy(const std::string &channelName, const StringVariantBaseMap &datafieldValues, bool triggerFilterUpdate=true)
Definition: Observer.cpp:665
project
std::string project
Definition: VisualizationRobot.cpp:82
armarx::Observer::updateDatafieldTimestamps
void updateDatafieldTimestamps(const std::string &channelName, const std::unordered_map< std::string, Ice::Long > &datafieldValues)
Definition: Observer.cpp:529
armarx::KinematicUnitObserver::reportJointStatuses
void reportJointStatuses(const NameStatusMap &jointStatuses, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitObserver.cpp:277
armarx::KinematicUnitObserver::onConnectObserver
void onConnectObserver() override
Framework hook.
Definition: KinematicUnitObserver.cpp:64
armarx::ConditionCheckUpdated
Definition: ConditionCheckUpdated.h:41
armarx::KinematicUnitObserver::ControlModeToString
static std::string ControlModeToString(ControlMode mode)
Definition: KinematicUnitObserver.h:100
armarx::Observer::setDataFieldFlatCopy
void setDataFieldFlatCopy(const std::string &channelName, const std::string &datafieldName, const VariantPtr &value, bool triggerFilterUpdate=true)
Definition: Observer.cpp:501
armarx::CMakePackageFinder::getDataDir
std::string getDataDir() const
Definition: CMakePackageFinder.h:176
armarx::VariantType::Long
const VariantTypeId Long
Definition: Variant.h:917
armarx::ConditionCheckEqualsWithTolerance
Definition: ConditionCheckEqualsWithTolerance.h:41
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:284
ConditionCheckEqualsWithTolerance.h
armarx::KinematicUnitObserver::reportJointAccelerations
void reportJointAccelerations(const NameValueMap &jointAccelerations, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c) override
Definition: KinematicUnitObserver.cpp:217
armarx::ConditionCheckInRange
Definition: ConditionCheckInRange.h:41
armarx::KinematicUnitObserver::initializedChannelsMutex
std::mutex initializedChannelsMutex
Definition: KinematicUnitObserver.h:158
armarx::control::njoint_controller::platform::platform_follower_controller::NameValueMap
std::map< std::string, float > NameValueMap
Definition: PlatformFollowerController.h:91
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:248
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:74
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:237
armarx::KinematicUnitObserver::createPropertyDefinitions
PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: KinematicUnitObserver.cpp:326
ConditionCheckSmaller.h
IceUtil::Handle< class PropertyDefinitionContainer >
armarx::ConditionCheckEquals
Definition: ConditionCheckEquals.h:46
armarx::Observer::offerConditionCheck
void offerConditionCheck(std::string checkName, ConditionCheck *conditionCheck)
Offer a condition check.
Definition: Observer.cpp:273
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:111
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:152
armarx::handleExceptions
void handleExceptions()
Definition: Exception.cpp:141
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:177
armarx::PropertyDefinitionsPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Definition: forward_declarations.h:34
armarx::KinematicUnitObserver::reportJointTorques
void reportJointTorques(const NameValueMap &jointTorques, Ice::Long timestamp, bool aValueChanged, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitObserver.cpp:197
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:187
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:28
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:153
armarx::TimedVariant
Definition: TimedVariant.h:40
ChannelRef.h
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:18
armarx::KinematicUnitObserver::initializedChannels
std::set< std::string > initializedChannels
Definition: KinematicUnitObserver.h:157
armarx::split
std::vector< std::string > split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelpers.cpp:36
ConditionCheckUpdated.h
armarx::Observer::offerChannel
void offerChannel(std::string channelName, std::string description)
Offer a channel.
Definition: Observer.cpp:126