Armar6Converter.cpp
Go to the documentation of this file.
1#include "Armar6Converter.h"
2
3#include <cstddef>
4
5#include <SimoxUtility/algorithm/advanced.h>
6#include <SimoxUtility/algorithm/get_map_keys_values.h>
7
8#include <RobotAPI/interface/units/RobotUnit/RobotUnitInterface.h>
12
13#include "ConverterTools.h"
14
16{
17
19 {
20 }
21
25
27 Armar6Converter::convert(const RobotUnitDataStreaming::TimeStep& data,
28 const RobotUnitDataStreaming::DataStreamingDescription& description)
29 {
30 arondto::Proprioception dto;
31 dto.iterationID = data.iterationId;
32
33 for (const auto& [dataEntryName, dataEntry] : description.entries)
34 {
35 process(dto, dataEntryName, {data, dataEntry});
36 }
37 return dto.toAron();
38 }
39
40 void
41 Armar6Converter::process(arondto::Proprioception& dto,
42 const std::string& entryName,
43 const ConverterValue& value)
44 {
45 const std::vector<std::string> split = simox::alg::split(entryName, ".", false, false);
47 const std::set<size_t> acceptedSizes{3, 4, 5};
48 ARMARX_CHECK_GREATER(acceptedSizes.count(split.size()), 0)
49 << "Data entry name could not be parsed (exected 3 or 4 or 5 components between '.'): "
50 << "\n- split: '" << split << "'";
51
52 const std::string& category = split.at(0);
53 const std::string& name = split.at(1);
54 const std::string& field = split.at(2);
55 ARMARX_CHECK_EQUAL(category, "sens") << category << " | " << entryName;
56
57 if (name == "Platform")
58 {
59 // Platform
60 processPlatformEntry(dto.platform, field, value);
61 }
62 else if (simox::alg::starts_with(name, "FT"))
63 {
64 // Force Torque
65 processForceTorqueEntry(dto.forceTorque, split, value);
66 }
67 else
68 {
69 // Joint
70 bool processed = processJointEntry(dto.joints, split, value);
71 if (not processed)
72 {
73 // Fallback: Put in extra.
74 const std::vector<std::string> comps{simox::alg::advanced(split.begin(), 1),
75 split.end()};
76 const std::string key = simox::alg::join(comps, ".");
77
78 switch (value.entry.type)
79 {
80 case RobotUnitDataStreaming::NodeTypeFloat:
81 dto.extraFloats[key] = getValueAs<float>(value);
82 break;
83 case RobotUnitDataStreaming::NodeTypeLong:
84 dto.extraLongs[key] = getValueAs<long>(value);
85 break;
86 case RobotUnitDataStreaming::NodeTypeBool:
87 dto.extraBools[key] = getValueAs<bool>(value);
88 break;
89 case RobotUnitDataStreaming::NodeTypeInt:
90 dto.extraInts[key] = getValueAs<int>(value);
91 break;
92 case RobotUnitDataStreaming::NodeTypeShort:
93 dto.extraShorts[key] = getValueAs<Ice::Short>(value);
94 break;
95 case RobotUnitDataStreaming::NodeTypeByte:
96 dto.extraBytes[key] = getValueAs<Ice::Byte>(value);
97 break;
98 default:
100 << "Cannot handle extra field '" << key << "' of type "
101 << RobotUnitDataStreaming::DataEntryNames.to_name(value.entry.type);
102 break;
103 }
104 }
105 }
106 }
107
108 void
109 Armar6Converter::processPlatformEntry(prop::arondto::Platform& dto,
110 const std::string& fieldName,
111 const ConverterValue& value)
112 {
113 if (findByPrefix(fieldName, tools->platformIgnored))
114 {
115 return;
116 }
117 else if (auto getter = findByPrefix(fieldName, tools->platformPoseGetters))
118 {
119 if (Eigen::Vector3f* dst = getter(dto))
120 {
121 if (auto setter = findBySuffix(fieldName, tools->vector3fSetters))
122 {
123 setter(*dst, getValueAs<float>(value));
124 }
125 }
126 }
127 else
128 {
129 // No setter for this field. Put in extra.
130 dto.extra[fieldName] = getValueAs<float>(value);
131 }
132 }
133
134 void
135 Armar6Converter::processForceTorqueEntry(std::map<std::string, prop::arondto::ForceTorque>& fts,
136 const std::vector<std::string>& split,
137 const ConverterValue& value)
138 {
139 const std::string& name = split.at(1);
140 std::vector<std::string> splitName = simox::alg::split(name, " ", false, false);
141 ARMARX_CHECK_EQUAL(splitName.size(), 2);
142 ARMARX_CHECK_EQUAL(splitName.at(0), "FT");
143
144 auto it = tools->sidePrefixMap.find(splitName.at(1));
145 ARMARX_CHECK(it != tools->sidePrefixMap.end()) << splitName.at(1);
146
147 const std::string& side = it->second;
148 processForceTorqueEntry(fts[side], split, value);
149 }
150
151 void
152 Armar6Converter::processForceTorqueEntry(prop::arondto::ForceTorque& dto,
153 const std::vector<std::string>& split,
154 const ConverterValue& value)
155 {
156 const std::string& fieldName = split.at(2);
157 if (auto getter = findByPrefix(fieldName, tools->ftGetters))
158 {
159 if (Eigen::Vector3f* dst = getter(dto))
160 {
161 if (auto setter = findBySuffix(fieldName, tools->vector3fSetters))
162 {
163 setter(*dst, getValueAs<float>(value));
164 }
165 }
166 }
167 else
168 {
169 // No setter for this field. Put in extra.
170 std::string key = split.size() == 4 ? (fieldName + "." + split.at(3)) : fieldName;
171
172 switch (value.entry.type)
173 {
174 case RobotUnitDataStreaming::NodeTypeFloat:
175 dto.extra[key] = getValueAs<float>(value);
176 break;
177 case RobotUnitDataStreaming::NodeTypeInt:
178 dto.extra[key] = getValueAs<int>(value);
179 break;
180 case RobotUnitDataStreaming::NodeTypeLong:
181 dto.extra[key] = getValueAs<long>(value);
182 break;
183 default:
184 ARMARX_DEBUG << "Cannot handle extra field '" << key << "' of type "
186 value.entry.type);
187 break;
188 }
189 }
190 }
191
192 bool
193 Armar6Converter::processJointEntry(prop::arondto::Joints& dto,
194 const std::vector<std::string>& split,
195 const ConverterValue& value)
196 {
197 const std::string& jointName = split.at(1);
198 const std::string& fieldName = split.at(2);
199 if (false)
200 {
201 // Only in simulation.
202 if (auto getter = findByPrefix(fieldName, tools->jointGetters))
203 {
204 if (std::map<std::string, float>* map = getter(dto))
205 {
206 (*map)[jointName] = getValueAs<float>(value);
207 }
208 }
209 }
210
211 const std::string tempSuffix = "Temperature";
212 if (simox::alg::ends_with(split.at(2), tempSuffix))
213 {
214 // Handle "dieTemperature" etc
215 const std::string name = split.at(2).substr(0, split.at(2).size() - tempSuffix.size());
216 dto.temperature[split.at(1)][name] = getValueAs<float>(value);
217 return true;
218 }
219 else if (auto it = tools->jointSetters.find(fieldName); it != tools->jointSetters.end())
220 {
221 const ConverterTools::JointSetter& setter = it->second;
222 setter(dto, split, value);
223 return true;
224 }
225 else
226 {
227 // ARMARX_DEBUG << "Ignoring unhandled field: '" << simox::alg::join(split, ".") << "'";
228 return false;
229 }
230 }
231
232} // namespace armarx::armem::server::robot_state::proprioception
aron::data::DictPtr convert(const RobotUnitDataStreaming::TimeStep &data, const RobotUnitDataStreaming::DataStreamingDescription &description) override
void process(arondto::Proprioception &dto, const std::string &entryName, const ConverterValue &value)
std::function< void(prop::arondto::Joints &dto, const std::vector< std::string > &split, const ConverterValue &value)> JointSetter
#define ARMARX_CHECK_GREATER(lhs, rhs)
This macro evaluates whether lhs is greater (>) than rhs and if it turns out to be false it will thro...
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_GREATER_EQUAL(lhs, rhs)
This macro evaluates whether lhs is greater or equal (>=) rhs and if it turns out to be false it will...
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
const simox::meta::EnumNames< DataEntryType > DataEntryNames
ValueT findBySuffix(const std::string &key, const std::map< std::string, ValueT > &map)
std::optional< std::string > findByPrefix(const std::string &key, const std::set< std::string > &prefixes)
Search.
std::shared_ptr< Dict > DictPtr
Definition Dict.h:42
std::vector< std::string > split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
std::shared_ptr< Value > value()
Definition cxxopts.hpp:855