ObjectInfo.cpp
Go to the documentation of this file.
1 #include "ObjectInfo.h"
2 
3 #include <filesystem>
4 #include <optional>
5 
6 #include <SimoxUtility/algorithm/string.h>
7 #include <SimoxUtility/json.h>
8 #include <SimoxUtility/shapes/AxisAlignedBoundingBox.h>
9 #include <SimoxUtility/shapes/OrientedBox.h>
10 
14 
15 namespace armarx
16 {
17  namespace fs = std::filesystem;
18 
19  ObjectInfo::ObjectInfo(const std::string& packageName,
20  const ObjectInfo::path& packageDataDir,
21  const path& relObjectsPath,
22  const ObjectID& id) :
23  _packageName(packageName),
24  _absPackageDataDir(packageDataDir),
25  _relObjectsPath(relObjectsPath),
26  _id(id)
27  {
28  }
29 
30  ObjectInfo::ObjectInfo(const std::string& packageName,
31  const ObjectInfo::path& packageDataDir,
32  const path& relObjectsPath,
33  const std::string& dataset,
34  const std::string& className) :
35  _packageName(packageName),
36  _absPackageDataDir(packageDataDir),
37  _relObjectsPath(relObjectsPath),
38  _id(dataset, className)
39  {
40  }
41 
42  void
44  {
45  this->_logError = enabled;
46  }
47 
48  std::string
50  {
51  return _packageName;
52  }
53 
54  std::string
56  {
57  return _id.dataset();
58  }
59 
60  std::string
62  {
63  return _id.className();
64  }
65 
66  ObjectID
68  {
69  return _id;
70  }
71 
72  std::string
74  {
75  return _id.str();
76  }
77 
79  ObjectInfo::objectDirectory(const bool fixDataPath) const
80  {
81  if (fixDataPath)
82  {
83  return _relObjectsPath / _id.dataset() / _id.className();
84  }
85 
86  return path(_packageName) / _relObjectsPath / _id.dataset() / _id.className();
87  }
88 
89  PackageFileLocation
90  ObjectInfo::file(const std::string& _extension,
91  const std::string& suffix,
92  const bool fixDataPath) const
93  {
94  std::string extension = _extension;
95  if (extension.at(0) != '.')
96  {
97  extension = "." + extension;
98  }
99  std::string filename = _id.className() + suffix + extension;
100 
102  loc.package = _packageName;
103  loc.relativePath = objectDirectory(fixDataPath) / filename;
104  loc.absolutePath = _absPackageDataDir / objectDirectory(false) / filename;
105  return loc;
106  }
107 
110  {
111  return file(".xml");
112  }
113 
116  {
117  return file(".urdf");
118  }
119 
122  {
123  return file(".sdf");
124  }
125 
126  std::optional<PackageFileLocation>
128  {
129  if (fs::is_regular_file(simoxXML().absolutePath))
130  {
131  return simoxXML();
132  }
133  else if (fs::is_regular_file(urdf().absolutePath))
134  {
135  return urdf();
136  }
137  else if (fs::is_regular_file(sdf().absolutePath))
138  {
139  return sdf();
140  }
141  else
142  {
143  return std::nullopt;
144  }
145  }
146 
149  {
150  return file(".xml", "_articulated", true);
151  }
152 
155  {
156  return file(".urdf", "_articulated", true);
157  }
158 
161  {
162  return file(".sdf", "_articulated");
163  }
164 
165  std::optional<PackageFileLocation>
167  {
168  if (fs::is_regular_file(articulatedSimoxXML().absolutePath))
169  {
170  return articulatedSimoxXML();
171  }
172  else if (fs::is_regular_file(articulatedUrdf().absolutePath))
173  {
174  return articulatedUrdf();
175  }
176  else if (fs::is_regular_file(articulatedSdf().absolutePath))
177  {
178  return articulatedSdf();
179  }
180  else
181  {
182  return std::nullopt;
183  }
184  }
185 
188  {
189  return file(".wrl");
190  }
191 
194  {
195  return file(".obj");
196  }
197 
200  {
201  return file(".json", "_bb");
202  }
203 
206  {
207  return file(".json", "_names");
208  }
209 
210  std::optional<simox::AxisAlignedBoundingBox>
212  {
213  nlohmann::json j;
214  try
215  {
216  ARMARX_CHECK(std::filesystem::exists(boundingBoxJson().absolutePath));
217  j = nlohmann::read_json(boundingBoxJson().absolutePath);
218  }
219  catch (const std::exception& e)
220  {
221  if (_logError)
222  {
223  ARMARX_ERROR << e.what();
224  }
225  return std::nullopt;
226  }
227 
228  try
229  {
230 
231  nlohmann::json jaabb = j.at("aabb");
232  auto center = jaabb.at("center").get<Eigen::Vector3f>();
233  auto extents = jaabb.at("extents").get<Eigen::Vector3f>();
234  auto min = jaabb.at("min").get<Eigen::Vector3f>();
235  auto max = jaabb.at("max").get<Eigen::Vector3f>();
236 
238 
239  static const float prec = 1e-3f;
240  ARMARX_CHECK_LESS_EQUAL((aabb.center() - center).norm(), prec)
241  << aabb.center().transpose() << "\n"
242  << center.transpose() << "\n"
243  << id();
244  ARMARX_CHECK_LESS_EQUAL((aabb.extents() - extents).norm(), prec)
245  << aabb.extents().transpose() << "\n"
246  << extents.transpose() << "\n"
247  << id();
248  ARMARX_CHECK_LESS_EQUAL((aabb.min() - min).norm(), prec)
249  << aabb.min().transpose() << "\n"
250  << min.transpose() << "\n"
251  << id();
252  ARMARX_CHECK_LESS_EQUAL((aabb.max() - max).norm(), prec)
253  << aabb.max().transpose() << "\n"
254  << max.transpose() << "\n"
255  << id();
256 
257  return aabb;
258  }
259  catch (...)
260  {
262  }
263 
264  return std::nullopt;
265  }
266 
267  std::optional<simox::OrientedBox<float>>
269  {
270  nlohmann::json j;
271  try
272  {
273  ARMARX_CHECK(std::filesystem::exists(boundingBoxJson().absolutePath));
274  j = nlohmann::read_json(boundingBoxJson().absolutePath);
275  }
276  catch (const std::exception& e)
277  {
278  if (_logError)
279  {
280  ARMARX_ERROR << e.what();
281  }
282  return std::nullopt;
283  }
284 
285  try
286  {
287  nlohmann::json joobb = j.at("oobb");
288  auto pos = joobb.at("pos").get<Eigen::Vector3f>();
289  auto ori = joobb.at("ori").get<Eigen::Quaternionf>().toRotationMatrix();
290  auto extents = joobb.at("extents").get<Eigen::Vector3f>();
291 
292  Eigen::Vector3f corner = pos - ori * extents / 2;
293 
295  corner, ori.col(0) * extents(0), ori.col(1) * extents(1), ori.col(2) * extents(2));
296 
297  static const float prec = 1e-3f;
298  ARMARX_CHECK(oobb.rotation().isApprox(ori, prec)) << oobb.rotation() << "\n"
299  << ori << "\n"
300  << id();
301  // If the object is too large, the above precision will trigger a false positive.
302  if (extents.squaredNorm() < 1e5f * 1e5f)
303  {
304  ARMARX_CHECK_LESS_EQUAL((oobb.center() - pos).norm(), prec)
305  << VAROUT(oobb.center().transpose()) << "\n"
306  << VAROUT(pos.transpose()) << "\n"
307  << VAROUT(extents.norm()) << "\n"
308  << VAROUT(id());
309  ARMARX_CHECK_LESS_EQUAL((oobb.dimensions() - extents).norm(), prec)
310  << VAROUT(oobb.dimensions().transpose()) << "\n"
311  << VAROUT(extents.transpose()) << "\n"
312  << VAROUT(extents.norm()) << "\n"
313  << VAROUT(id());
314  }
315  return oobb;
316  }
317  catch (...)
318  {
320  }
321 
322  return std::nullopt;
323  }
324 
325  std::optional<std::vector<std::string>>
327  {
328  return loadNames("recognized_name");
329  }
330 
331  std::optional<std::vector<std::string>>
333  {
334  return loadNames("spoken_name");
335  }
336 
337  std::optional<std::vector<std::string>>
338  ObjectInfo::loadNames(const std::string& jsonKey) const
339  {
341  if (fs::is_regular_file(file.absolutePath))
342  {
343  nlohmann::json json;
344 
345  try
346  {
347  json = nlohmann::read_json(file.absolutePath);
348  }
349  catch (const nlohmann::json::exception& e)
350  {
351  if (_logError)
352  {
353  ARMARX_WARNING << "Failed to parse JSON file " << file.absolutePath << ": \n"
354  << e.what();
355  }
356  return std::nullopt;
357  }
358  catch (const std::exception& e)
359  {
360  if (_logError)
361  {
362  ARMARX_WARNING << "Failed to read file " << file.absolutePath << ": \n"
363  << e.what();
364  }
365  return std::nullopt;
366  }
367 
368  return json.at(jsonKey).get<std::vector<std::string>>();
369  }
370  else
371  {
372  return std::nullopt;
373  }
374  }
375 
376  bool
378  {
379  namespace fs = std::filesystem;
380  bool result = true;
381 
382  if (!fs::is_regular_file(simoxXML().absolutePath))
383  {
384  if (_logError)
385  {
386  ARMARX_WARNING << "Expected simox object file for object " << *this << ": "
387  << simoxXML().absolutePath;
388  }
389  result = false;
390  }
391  if (false and not fs::is_regular_file(wavefrontObj().absolutePath))
392  {
393  if (_logError)
394  {
395  ARMARX_WARNING << "Expected wavefront object file (.obj) for object " << *this
396  << ": " << wavefrontObj().absolutePath;
397  }
398  result = false;
399  }
400 
401  return result;
402  }
403 
404 } // namespace armarx
405 
406 std::ostream&
407 armarx::operator<<(std::ostream& os, const ObjectInfo& rhs)
408 {
409  return os << rhs.id();
410 }
armarx::ObjectInfo::articulatedSdf
PackageFileLocation articulatedSdf() const
Definition: ObjectInfo.cpp:160
armarx::ObjectID
A known object ID of the form "Dataset/ClassName" or "Dataset/ClassName/InstanceName".
Definition: ObjectID.h:11
LocalException.h
armarx::ObjectInfo::articulatedSimoxXML
PackageFileLocation articulatedSimoxXML() const
Definition: ObjectInfo.cpp:148
armarx::ObjectID::dataset
std::string dataset() const
Definition: ObjectID.h:24
armarx::ObjectInfo::className
std::string className() const
Definition: ObjectInfo.cpp:61
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:19
armarx::ObjectInfo::wavefrontObj
PackageFileLocation wavefrontObj() const
Definition: ObjectInfo.cpp:193
armarx::ObjectInfo::articulatedUrdf
PackageFileLocation articulatedUrdf() const
Definition: ObjectInfo.cpp:154
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:377
armarx::ObjectInfo::urdf
PackageFileLocation urdf() const
Definition: ObjectInfo.cpp:115
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:326
armarx::ObjectInfo::file
PackageFileLocation file(const std::string &extension, const std::string &suffix="", bool fixDataPath=false) const
Definition: ObjectInfo.cpp:90
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::GetHandledExceptionString
std::string GetHandledExceptionString()
Definition: Exception.cpp:147
armarx::ObjectInfo::boundingBoxJson
PackageFileLocation boundingBoxJson() const
Definition: ObjectInfo.cpp:199
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:121
armarx::ObjectInfo::package
std::string package() const
Definition: ObjectInfo.cpp:49
enabled
std::atomic< bool > * enabled
Definition: RemoteGuiWidgetController.cpp:75
filename
std::string filename
Definition: VisualizationRobot.cpp:83
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:127
armarx::ObjectInfo::idStr
std::string idStr() const
Definition: ObjectInfo.cpp:73
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:109
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:55
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:268
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:211
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:332
armarx::ObjectInfo::id
ObjectID id() const
Return "dataset/name".
Definition: ObjectInfo.cpp:67
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:187
armarx::ObjectInfo::setLogError
void setLogError(bool enabled)
Definition: ObjectInfo.cpp:43
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:166
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:205
armarx::ObjectInfo
Accessor for the object files.
Definition: ObjectInfo.h:37