HapticObserver.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package
19 * @author
20 * @date
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24#include "HapticObserver.h"
25
26#include <Eigen/Dense>
27
34
37
38namespace armarx
39{
41 {
42 statisticsTask =
43 new PeriodicTask<HapticObserver>(this, &HapticObserver::updateStatistics, 10, false);
44 }
45
46 void
47 HapticObserver::setTopicName(std::string topicName)
48 {
49 this->topicName = topicName;
50 }
51
52 void
54 {
55 if (topicName.empty())
56 {
57 usingTopic(getProperty<std::string>("HapticTopicName").getValue());
58 }
59 else
60 {
61 usingTopic(topicName);
62 }
63
64 // register all checks
69 }
70
71 void
73 {
74 statisticsTask->start();
75 }
76
77 void
79 {
80 statisticsTask->stop();
81 }
82
83 void
84 HapticObserver::reportSensorValues(const std::string& device,
85 const std::string& name,
86 const armarx::MatrixFloatBasePtr& values,
87 const armarx::TimestampBasePtr& timestamp,
88 const Ice::Current&)
89 {
90 std::unique_lock lock(dataMutex);
91
92 MatrixFloatPtr matrix = MatrixFloatPtr::dynamicCast(values);
93 if (matrix->cols == 0)
94 {
95 // Empty matrix received, silently ignore
96 return;
97 }
98
99 TimestampVariantPtr timestampPtr = TimestampVariantPtr::dynamicCast(timestamp);
100 Eigen::MatrixXf eigenMatrix = matrix->toEigen();
101 float max = eigenMatrix.maxCoeff();
102 float mean = eigenMatrix.mean();
103 std::string channelName = name;
104 Eigen::MatrixXf M = matrix->toEigen();
105
106 if (!existsChannel(channelName))
107 {
108 offerChannel(channelName, "Haptic data");
110 channelName, "device", Variant(device), "Device of the tactile sensor");
112 channelName, "name", Variant(name), "Name of the tactile sensor");
113 offerDataFieldWithDefault(channelName, "matrix", matrix, "Raw tactile matrix data");
114 offerDataFieldWithDefault(channelName, "max", Variant(max), "Maximum value");
115 offerDataFieldWithDefault(channelName, "mean", Variant(mean), "Mean value");
116 offerDataFieldWithDefault(channelName, "timestamp", timestampPtr, "Timestamp");
117 offerDataFieldWithDefault(channelName, "rate", Variant(0.0f), "Sample rate");
118
119 for (int i = 0; i < M.rows(); i++)
120 {
121 for (int j = 0; j < M.cols(); j++)
122 {
123 std::stringstream s;
124 s << "entry_" << i << "," << j;
126 channelName, s.str(), Variant(M(i, j)), "Individual matrix entry");
127 }
128 }
129
130 ARMARX_INFO << "Offering new channel: " << channelName;
131 }
132 else
133 {
134 setDataField(channelName, "device", Variant(device));
135 setDataField(channelName, "name", Variant(name));
136 setDataField(channelName, "matrix", matrix);
137 setDataField(channelName, "max", Variant(max));
138 setDataField(channelName, "mean", Variant(mean));
139 setDataField(channelName, "timestamp", timestampPtr);
140
141 for (int i = 0; i < M.rows(); i++)
142 {
143 for (int j = 0; j < M.cols(); j++)
144 {
145 std::stringstream s;
146 s << "entry_" << i << "," << j;
147 setDataField(channelName, s.str(), Variant(M(i, j)));
148 }
149 }
150 }
151
152 /*if(statistics.count(device) > 0)
153 {
154 statistics.at(device).add(timestamp->timestamp);
155 HapticSampleStatistics stats = statistics.at(device);
156 long avg = stats.average();
157 float rate = avg == 0 ? 0 : 1000000.0f / (float)avg;
158 setDataField(device, "rate", Variant(rate));
159 }
160 else
161 {
162 statistics.insert(std::map<std::string,HapticSampleStatistics>::value_type(device, HapticSampleStatistics(100, timestamp->timestamp)));
163 }*/
164
165 updateChannel(channelName);
166 }
167
173
174 void
175 HapticObserver::updateStatistics()
176 {
177 /*std::unique_lock lock(dataMutex);
178 //ARMARX_LOG << "updateStatistics";
179 long now = TimestampVariant::nowLong();
180 for (std::map<std::string, HapticSampleStatistics>::iterator it = statistics.begin(); it != statistics.end(); ++it)
181 {
182 HapticSampleStatistics stats = it->second;
183 std::string device = it->first;
184 long avg = stats.average(now);
185 float rate = avg == 0 ? 0 : 1000000.0f / (float)avg;
186 setDataField(device, "rate", Variant(rate));
187 updateChannel(device);
188 }*/
189 }
190} // namespace armarx
std::string timestamp()
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 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.
void onConnectObserver() override
Framework hook.
void setTopicName(std::string topicName)
void onExitObserver() override
Framework hook.
void reportSensorValues(const ::std::string &device, const ::std::string &name, const ::armarx::MatrixFloatBasePtr &values, const ::armarx::TimestampBasePtr &timestamp, const ::Ice::Current &=Ice::emptyCurrent) override
PropertyDefinitionsPtr createPropertyDefinitions() override
void onInitObserver() override
Framework hook.
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
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 offerDataFieldWithDefault(std::string channelName, std::string datafieldName, const Variant &defaultValue, std::string description)
Offer a datafield with default value.
Definition Observer.cpp:160
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
The periodic task executes one thread method repeatedly using the time period specified in the constr...
The Variant class is described here: Variants.
Definition Variant.h:224
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::optional< float > mean(const boost::circular_buffer< NameValueMap > &buffer, const std::string &key)
IceInternal::Handle< MatrixFloat > MatrixFloatPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
std::vector< T > max(const std::vector< T > &v1, const std::vector< T > &v2)
IceInternal::Handle< TimestampVariant > TimestampVariantPtr