ObjectInfo.cpp
Go to the documentation of this file.
1 #include "ObjectInfo.h"
2 
3 #include <SimoxUtility/algorithm/string.h>
4 #include <SimoxUtility/json.h>
5 #include <SimoxUtility/shapes/AxisAlignedBoundingBox.h>
6 #include <SimoxUtility/shapes/OrientedBox.h>
7 
10 
11 
12 namespace armarx
13 {
14  namespace fs = std::filesystem;
15 
16 
17  ObjectInfo::ObjectInfo(const std::string& packageName, const ObjectInfo::path& packageDataDir,
18  const path& relObjectsPath, const ObjectID& id) :
19  _packageName(packageName), _absPackageDataDir(packageDataDir),
20  _relObjectsPath(relObjectsPath), _id(id)
21  {
22  }
23 
24  ObjectInfo::ObjectInfo(const std::string& packageName, const ObjectInfo::path& packageDataDir,
25  const path& relObjectsPath,
26  const std::string& dataset, const std::string& className) :
27  _packageName(packageName), _absPackageDataDir(packageDataDir),
28  _relObjectsPath(relObjectsPath), _id(dataset, className)
29  {
30  }
31 
33  {
34  this->_logError = enabled;
35  }
36 
37  std::string ObjectInfo::package() const
38  {
39  return _packageName;
40  }
41 
42  std::string ObjectInfo::dataset() const
43  {
44  return _id.dataset();
45  }
46 
47  std::string ObjectInfo::className() const
48  {
49  return _id.className();
50  }
51 
53  {
54  return _id;
55  }
56 
57  std::string ObjectInfo::idStr() const
58  {
59  return _id.str();
60  }
61 
62  ObjectInfo::path ObjectInfo::objectDirectory(const bool fixDataPath) const
63  {
64  if(fixDataPath)
65  {
66  return _relObjectsPath / _id.dataset() / _id.className();
67  }
68 
69  return path(_packageName) / _relObjectsPath / _id.dataset() / _id.className();
70  }
71 
72  PackageFileLocation ObjectInfo::file(const std::string& _extension, const std::string& suffix, const bool fixDataPath) const
73  {
74  std::string extension = _extension;
75  if (extension.at(0) != '.')
76  {
77  extension = "." + extension;
78  }
79  std::string filename = _id.className() + suffix + extension;
80 
82  loc.package = _packageName;
83  loc.relativePath = objectDirectory(fixDataPath) / filename;
84  loc.absolutePath = _absPackageDataDir / objectDirectory(false) / filename;
85  return loc;
86  }
87 
88 
90  {
91  return file(".xml");
92  }
93 
95  {
96  return file(".urdf");
97  }
98 
100  {
101  return file(".sdf");
102  }
103 
104  std::optional<PackageFileLocation> ObjectInfo::getModel() const
105  {
106  if (fs::is_regular_file(simoxXML().absolutePath))
107  {
108  return simoxXML();
109  }
110  else if (fs::is_regular_file(urdf().absolutePath))
111  {
112  return urdf();
113  }
114  else if (fs::is_regular_file(sdf().absolutePath))
115  {
116  return sdf();
117  }
118  else
119  {
120  return std::nullopt;
121  }
122  }
123 
125  {
126  return file(".xml", "_articulated", true);
127  }
128 
130  {
131  return file(".urdf", "_articulated", true);
132  }
133 
135  {
136  return file(".sdf", "_articulated");
137  }
138 
139  std::optional<PackageFileLocation> ObjectInfo::getArticulatedModel() const
140  {
141  if (fs::is_regular_file(articulatedSimoxXML().absolutePath))
142  {
143  return articulatedSimoxXML();
144  }
145  else if (fs::is_regular_file(articulatedUrdf().absolutePath))
146  {
147  return articulatedUrdf();
148  }
149  else if (fs::is_regular_file(articulatedSdf().absolutePath))
150  {
151  return articulatedSdf();
152  }
153  else
154  {
155  return std::nullopt;
156  }
157  }
158 
159 
160 
162  {
163  return file(".wrl");
164  }
165 
167  {
168  return file(".obj");
169  }
170 
172  {
173  return file(".json", "_bb");
174  }
175 
177  {
178  return file(".json", "_names");
179  }
180 
181  std::optional<simox::AxisAlignedBoundingBox> ObjectInfo::loadAABB() const
182  {
183  nlohmann::json j;
184  try
185  {
186  j = nlohmann::read_json(boundingBoxJson().absolutePath);
187  }
188  catch (const std::exception& e)
189  {
190  if (_logError)
191  {
192  ARMARX_ERROR << e.what();
193  }
194  return std::nullopt;
195  }
196 
197  nlohmann::json jaabb = j.at("aabb");
198  auto center = jaabb.at("center").get<Eigen::Vector3f>();
199  auto extents = jaabb.at("extents").get<Eigen::Vector3f>();
200  auto min = jaabb.at("min").get<Eigen::Vector3f>();
201  auto max = jaabb.at("max").get<Eigen::Vector3f>();
202 
204 
205  static const float prec = 1e-3f;
206  ARMARX_CHECK_LESS_EQUAL((aabb.center() - center).norm(), prec) << aabb.center().transpose() << "\n" << center.transpose() << "\n" << id();
207  ARMARX_CHECK_LESS_EQUAL((aabb.extents() - extents).norm(), prec) << aabb.extents().transpose() << "\n" << extents.transpose() << "\n" << id();
208  ARMARX_CHECK_LESS_EQUAL((aabb.min() - min).norm(), prec) << aabb.min().transpose() << "\n" << min.transpose() << "\n" << id();
209  ARMARX_CHECK_LESS_EQUAL((aabb.max() - max).norm(), prec) << aabb.max().transpose() << "\n" << max.transpose() << "\n" << id();
210 
211  return aabb;
212  }
213 
214  std::optional<simox::OrientedBox<float>> ObjectInfo::loadOOBB() const
215  {
216  nlohmann::json j;
217  try
218  {
219  j = nlohmann::read_json(boundingBoxJson().absolutePath);
220  }
221  catch (const std::exception& e)
222  {
223  if (_logError)
224  {
225  ARMARX_ERROR << e.what();
226  }
227  return std::nullopt;
228  }
229 
230  nlohmann::json joobb = j.at("oobb");
231  auto pos = joobb.at("pos").get<Eigen::Vector3f>();
232  auto ori = joobb.at("ori").get<Eigen::Quaternionf>().toRotationMatrix();
233  auto extents = joobb.at("extents").get<Eigen::Vector3f>();
234 
235  Eigen::Vector3f corner = pos - ori * extents / 2;
236 
237  simox::OrientedBox<float> oobb(corner,
238  ori.col(0) * extents(0),
239  ori.col(1) * extents(1),
240  ori.col(2) * extents(2));
241 
242  static const float prec = 1e-3f;
243  ARMARX_CHECK(oobb.rotation().isApprox(ori, prec)) << oobb.rotation() << "\n" << ori << "\n" << id();
244  // If the object is too large, the above precision will trigger a false positive.
245  if (extents.squaredNorm() < 1e5f * 1e5f)
246  {
247  ARMARX_CHECK_LESS_EQUAL((oobb.center() - pos).norm(), prec)
248  << VAROUT(oobb.center().transpose())
249  << "\n" << VAROUT(pos.transpose())
250  << "\n" << VAROUT(extents.norm())
251  << "\n" << VAROUT(id());
252  ARMARX_CHECK_LESS_EQUAL((oobb.dimensions() - extents).norm(), prec)
253  << VAROUT(oobb.dimensions().transpose())
254  << "\n" << VAROUT(extents.transpose())
255  << "\n" << VAROUT(extents.norm())
256  << "\n" << VAROUT(id());
257  }
258  return oobb;
259  }
260 
261  std::optional<std::vector<std::string>> ObjectInfo::loadRecognizedNames() const
262  {
263  return loadNames("recognized_name");
264  }
265 
266  std::optional<std::vector<std::string>> ObjectInfo::loadSpokenNames() const
267  {
268  return loadNames("spoken_name");
269  }
270 
271  std::optional<std::vector<std::string> > ObjectInfo::loadNames(const std::string& jsonKey) const
272  {
274  if (fs::is_regular_file(file.absolutePath))
275  {
276  nlohmann::json json;
277 
278  try
279  {
280  json = nlohmann::read_json(file.absolutePath);
281  }
282  catch (const nlohmann::json::exception& e)
283  {
284  if (_logError)
285  {
286  ARMARX_WARNING << "Failed to parse JSON file " << file.absolutePath << ": \n" << e.what();
287  }
288  return std::nullopt;
289  }
290  catch (const std::exception& e)
291  {
292  if (_logError)
293  {
294  ARMARX_WARNING << "Failed to read file " << file.absolutePath << ": \n" << e.what();
295  }
296  return std::nullopt;
297  }
298 
299  return json.at(jsonKey).get<std::vector<std::string>>();
300  }
301  else
302  {
303  return std::nullopt;
304  }
305  }
306 
307 
309  {
310  namespace fs = std::filesystem;
311  bool result = true;
312 
313  if (!fs::is_regular_file(simoxXML().absolutePath))
314  {
315  if (_logError)
316  {
317  ARMARX_WARNING << "Expected simox object file for object " << *this << ": " << simoxXML().absolutePath;
318  }
319  result = false;
320  }
321  if (false and not fs::is_regular_file(wavefrontObj().absolutePath))
322  {
323  if (_logError)
324  {
325  ARMARX_WARNING << "Expected wavefront object file (.obj) for object " << *this << ": " << wavefrontObj().absolutePath;
326  }
327  result = false;
328  }
329 
330  return result;
331  }
332 
333 }
334 
335 
336 std::ostream& armarx::operator<<(std::ostream& os, const ObjectInfo& rhs)
337 {
338  return os << rhs.id();
339 }
armarx::ObjectInfo::articulatedSdf
PackageFileLocation articulatedSdf() const
Definition: ObjectInfo.cpp:134
armarx::ObjectID
A known object ID of the form "Dataset/ClassName" or "Dataset/ClassName/InstanceName".
Definition: ObjectID.h:11
armarx::ObjectInfo::articulatedSimoxXML
PackageFileLocation articulatedSimoxXML() const
Definition: ObjectInfo.cpp:124
armarx::ObjectID::dataset
std::string dataset() const
Definition: ObjectID.h:24
armarx::ObjectInfo::className
std::string className() const
Definition: ObjectInfo.cpp:47
armarx::max
std::vector< T > max(const std::vector< T > &v1, const std::vector< T > &v2)
Definition: VectorHelpers.h:267
armarx::ObjectInfo::ObjectInfo
ObjectInfo(const std::string &packageName, const path &absPackageDataDir, const path &relObjectsPath, const ObjectID &id)
ObjectInfo.
Definition: ObjectInfo.cpp:17
armarx::ObjectInfo::wavefrontObj
PackageFileLocation wavefrontObj() const
Definition: ObjectInfo.cpp:166
armarx::ObjectInfo::articulatedUrdf
PackageFileLocation articulatedUrdf() const
Definition: ObjectInfo.cpp:129
armarx::PackageFileLocation
Definition: ObjectInfo.h:22
armarx::PackageFileLocation::relativePath
std::string relativePath
Relative to the package's data directory.
Definition: ObjectInfo.h:28
armarx::ObjectInfo::checkPaths
virtual bool checkPaths() const
Checks the existence of expected files.
Definition: ObjectInfo.cpp:308
armarx::ObjectInfo::urdf
PackageFileLocation urdf() const
Definition: ObjectInfo.cpp:94
armarx::ObjectInfo::loadRecognizedNames
std::optional< std::vector< std::string > > loadRecognizedNames() const
Load names to use when matched when recognizing an object by name.
Definition: ObjectInfo.cpp:261
armarx::ObjectInfo::file
PackageFileLocation file(const std::string &extension, const std::string &suffix="", bool fixDataPath=false) const
Definition: ObjectInfo.cpp:72
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
armarx::aron::simox::arondto::AxisAlignedBoundingBox
::simox::arondto::AxisAlignedBoundingBox AxisAlignedBoundingBox
Definition: simox.h:14
armarx::ObjectInfo::boundingBoxJson
PackageFileLocation boundingBoxJson() const
Definition: ObjectInfo.cpp:171
armarx::ObjectID::className
std::string className() const
Definition: ObjectID.h:28
armarx::ObjectInfo::path
std::filesystem::path path
Definition: ObjectInfo.h:40
armarx::ObjectInfo::sdf
PackageFileLocation sdf() const
Definition: ObjectInfo.cpp:99
armarx::ObjectInfo::package
std::string package() const
Definition: ObjectInfo.cpp:37
enabled
std::atomic< bool > * enabled
Definition: RemoteGuiWidgetController.cpp:75
filename
std::string filename
Definition: VisualizationRobot.cpp:84
ObjectInfo.h
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
armarx::ObjectInfo::getModel
std::optional< PackageFileLocation > getModel() const
Return the Simox XML, URDF or SDF, if one exists.
Definition: ObjectInfo.cpp:104
armarx::ObjectInfo::idStr
std::string idStr() const
Definition: ObjectInfo.cpp:57
ARMARX_CHECK_LESS_EQUAL
#define ARMARX_CHECK_LESS_EQUAL(lhs, rhs)
This macro evaluates whether lhs is less or equal (<=) rhs and if it turns out to be false it will th...
Definition: ExpressionException.h:109
armarx::ObjectInfo::simoxXML
PackageFileLocation simoxXML() const
Definition: ObjectInfo.cpp:89
armarx::PackageFileLocation::package
std::string package
Name of the ArmarX package.
Definition: ObjectInfo.h:25
ExpressionException.h
armarx::ObjectInfo::dataset
std::string dataset() const
Definition: ObjectInfo.cpp:42
armarx::ObjectInfo::loadOOBB
std::optional< simox::OrientedBox< float > > loadOOBB() const
Load the OOBB (object-oriented bounding box) from the bounding box JSON file.
Definition: ObjectInfo.cpp:214
armarx::ObjectInfo::loadAABB
std::optional< simox::AxisAlignedBoundingBox > loadAABB() const
Load the AABB (axis-aligned bounding-box) from the bounding box JSON file.
Definition: ObjectInfo.cpp:181
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:182
armarx::PackageFileLocation::absolutePath
std::filesystem::path absolutePath
The absolute path (in the host's file system).
Definition: ObjectInfo.h:30
armarx::Quaternion< float, 0 >
armarx::min
std::vector< T > min(const std::vector< T > &v1, const std::vector< T > &v2)
Definition: VectorHelpers.h:294
simox::OrientedBox
Definition: ice_conversions.h:18
armarx::ObjectInfo::loadSpokenNames
std::optional< std::vector< std::string > > loadSpokenNames() const
Load names to use when verbalizing an object name.
Definition: ObjectInfo.cpp:266
armarx::ObjectInfo::id
ObjectID id() const
Return "dataset/name".
Definition: ObjectInfo.cpp:52
armarx::operator<<
std::ostream & operator<<(std::ostream &os, const PythonApplicationManager::Paths &paths)
Definition: PythonApplicationManager.cpp:221
armarx::ObjectInfo::meshWrl
PackageFileLocation meshWrl() const
Definition: ObjectInfo.cpp:161
armarx::ObjectInfo::setLogError
void setLogError(bool enabled)
Definition: ObjectInfo.cpp:32
Logging.h
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::ObjectInfo::getArticulatedModel
std::optional< PackageFileLocation > getArticulatedModel() const
Return the articulated Simox XML, URDF or SDF, if one exists.
Definition: ObjectInfo.cpp:139
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::ObjectID::str
std::string str() const
Return "dataset/className" or "dataset/className/instanceName".
Definition: ObjectID.cpp:55
armarx::ObjectInfo::namesJson
PackageFileLocation namesJson() const
File containing recognized and spoken names of objects.
Definition: ObjectInfo.cpp:176
armarx::ObjectInfo
Accessor for the object files.
Definition: ObjectInfo.h:37