Segment.cpp
Go to the documentation of this file.
1#include "Segment.h"
2
3#include <filesystem>
4
5#include <SimoxUtility/algorithm/string/string_tools.h>
6#include <SimoxUtility/color/Color.h>
7#include <SimoxUtility/math/pose/pose.h>
8#include <SimoxUtility/shapes/AxisAlignedBoundingBox.h>
9#include <SimoxUtility/shapes/OrientedBox.h>
10
14
17#include <RobotAPI/libraries/armem_objects/aron/ObjectClass.aron.generated.h>
22
24{
25
27 SpecializedCoreSegment(memoryToIceAdapter,
28 objects::classSegmentID.coreSegmentName,
29 arondto::ObjectClass::ToAronType(),
30 -1)
31 {
32 }
33
35 {
36 }
37
38 void
40 {
41 SpecializedCoreSegment::defineProperties(defs, prefix);
42
43 defs->optional(p.objectsPackage,
44 prefix + "ObjectsPackage",
45 "Name of the objects package to load from.");
46 defs->optional(p.loadFromObjectsPackage,
47 prefix + "LoadFromObjectsPackage",
48 "If true, load the objects from the objects package on startup.");
49
50 floorVis.defineProperties(defs, prefix + "Floor.");
51 }
52
53 void
55 {
56 SpecializedCoreSegment::init();
57
58 if (p.loadFromObjectsPackage)
59 {
60 ARMARX_VERBOSE << "Loading objects from package `" << p.objectsPackage << "`.";
61 loadByObjectFinder(p.objectsPackage);
62 }
63 }
64
65 void
67 {
68 if (p.loadFromObjectsPackage)
69 {
70 ARMARX_VERBOSE << "Loading objects from package `" << p.objectsPackage << "`.";
71 loadByObjectFinder(p.objectsPackage);
72 }
73 else
74 {
75 ARMARX_INFO << "Loading object from package in `reloadObjectClassesByObjectFinder()` "
76 "is disabled via property. No object classes will be reloaded!";
77 }
78 }
79
80 void
82 {
83 this->arviz = arviz;
84
85 floorVis.setArViz(arviz);
86 floorVis.updateFloorObject(*segmentPtr);
87 }
88
89 void
90 Segment::loadByObjectFinder(const std::string& objectsPackage)
91 {
93 loadByObjectFinder(ObjectFinder(objectsPackage));
94 }
95
96 void
98 {
99 this->objectFinder = finder;
101 }
102
103 void
105 {
107
108 const Time now = Time::Now();
109
110 const bool checkPaths = false;
111 std::vector<ObjectInfo> infos = objectFinder.findAllObjects(checkPaths);
112
113 const MemoryID providerID =
114 segmentPtr->id().withProviderSegmentName(objectFinder.getPackageName());
115 ARMARX_INFO << "Loading up to " << infos.size() << " object classes from '"
116 << objectFinder.getPackageName() << "' ...";
117 Commit commit;
118 for (ObjectInfo& info : infos)
119 {
121
122 ARMARX_VERBOSE << info.idStr();
123 info.setLogError(false);
124
125 EntityUpdate& update = commit.add();
126 update.entityID = providerID.withEntityName(info.id().str());
127 update.arrivedTime = update.referencedTime = update.sentTime = now;
128
130 ARMARX_VERBOSE << "object class from info";
131 arondto::ObjectClass objectClass = objectClassFromInfo(info);
132
133 armarx::ObjectID classID;
134 fromAron(objectClass.id, classID);
135 ARMARX_VERBOSE << VAROUT(classID);
136 update.instancesData = {objectClass.toAron()};
137 }
138
140
141 ARMARX_INFO << "Loaded " << commit.updates.size() << " object classes from '"
142 << objectFinder.getPackageName() << "'.";
143 iceMemory.commitLocking(commit);
144 }
145
146 void
147 Segment::visualizeClass(const MemoryID& entityID, bool showAABB, bool showOOBB)
148 {
149 const Eigen::Matrix4f pose = Eigen::Matrix4f::Identity();
150
151 viz::Layer layerOrigin = arviz.layer("Origin");
152 layerOrigin.add(viz::Pose("Origin"));
153
154 viz::Layer layerObject = arviz.layer("Class Model");
155 viz::Layer layerAABB = arviz.layer("Class AABB");
156 viz::Layer layerOOBB = arviz.layer("Class OOBB");
157
158 if (segmentPtr)
159 {
160 try
161 {
162 std::optional<arondto::ObjectClass> aron = doLocked(
163 [this, &entityID]()
164 {
165 return segmentPtr->findLatestInstanceDataAs<arondto::ObjectClass>(entityID,
166 0);
167 });
168 if (not aron.has_value())
169 {
170 return;
171 }
172
173 if (not aron->simoxXmlPath.package.empty())
174 {
175 layerObject.add(viz::Object(entityID.str())
176 .file(aron->simoxXmlPath.package, aron->simoxXmlPath.path)
177 .pose(pose));
178 }
179
180 if (showAABB)
181 {
182 layerAABB.add(viz::Box("AABB")
183 .pose(pose * simox::math::pose(aron->aabb.center))
184 .size(aron->aabb.extents)
185 .color(simox::Color::cyan(255, 64)));
186 }
187 if (showOOBB)
188 {
189 layerOOBB.add(viz::Box("OOBB")
190 .pose(pose * simox::math::pose(aron->oobb.center,
191 aron->oobb.orientation))
192 .size(aron->oobb.extents)
193 .color(simox::Color::lime(255, 64)));
194 }
195 }
196 catch (const armem::error::ArMemError& e)
197 {
198 ARMARX_INFO << "Failed to visualize object class " << entityID << "."
199 << "\nReason: " << e.what();
200 }
201 catch (const aron::error::AronException& e)
202 {
203 ARMARX_INFO << "Failed to visualize object class " << entityID << "."
204 << "\nReason: " << e.what();
205 }
206 }
207
208 arviz.commit({layerObject, layerOrigin, layerAABB, layerOOBB});
209 }
210
211 arondto::ObjectClass
213 {
214 namespace fs = std::filesystem;
215
216 // ARMARX_VERBOSE << info.idStr();
217
218 arondto::ObjectClass data;
219 toAron(data.id, info.id());
220
221 auto setPathIfExists = [](armarx::arondto::PackagePath& aron, PackageFileLocation location)
222 {
223 // if the location relative path starts withtthe package name, this must be removed. The armarx::PackagePath
224 // automatically adds the package when creating the absolute path
225 if (simox::alg::starts_with(location.relativePath, location.package))
226 {
227 // strip the package name and the "/"
228 location.relativePath = location.relativePath.substr(location.package.size() + 1);
229 }
230
231 if (fs::is_regular_file(location.absolutePath))
232 {
233 toAron(aron, location);
234 }
235 else
236 {
238 }
239 };
240 setPathIfExists(data.simoxXmlPath, info.simoxXML());
241 setPathIfExists(data.urdfPath, info.urdf());
242 setPathIfExists(data.sdfPath, info.sdf());
243 setPathIfExists(data.articulatedSimoxXmlPath, info.articulatedSimoxXML());
244 setPathIfExists(data.articulatedUrdfPath, info.articulatedUrdf());
245 setPathIfExists(data.articulatedSdfPath, info.articulatedSdf());
246 setPathIfExists(data.meshObjPath, info.wavefrontObj());
247 setPathIfExists(data.meshWrlPath, info.meshWrl());
248
250 ARMARX_VERBOSE << "AABB";
251 auto aabb = info.loadAABB();
252 toAron(data.aabb, aabb ? aabb.value() : simox::AxisAlignedBoundingBox());
253
255 auto oobb = info.loadOOBB();
256 ARMARX_VERBOSE << "OOBB";
257 toAron(data.oobb, oobb ? oobb.value() : simox::OrientedBoxf());
258
259 if (auto recogNames = info.loadRecognizedNames())
260 {
261 data.names.recognized = recogNames.value();
262 }
263 if (auto spokenNames = info.loadSpokenNames())
264 {
265 data.names.spoken = spokenNames.value();
266 }
267
268 return data;
269 }
270
271 void
273 {
274 using namespace armarx::RemoteGui::Client;
275
276 data.setup(segment);
277 visu.setup(segment);
278
279 VBoxLayout layout;
280 layout.addChildren({data.group, visu.group});
281
282 group = {};
283 group.setLabel("Class");
284 group.addChildren({layout, VSpacer()});
285 }
286
287 void
289 {
290 data.update(segment);
291 visu.update(segment);
292 }
293
294 void
296 {
297 using namespace armarx::RemoteGui::Client;
298
299 reloadButton.setLabel("Reload");
300
301 maxHistorySize.setValue(std::max(1, int(segment.properties.maxHistorySize)));
302 maxHistorySize.setRange(1, 1e6);
303 infiniteHistory.setValue(segment.properties.maxHistorySize == -1);
304
305 GridLayout grid;
306 int row = 0;
307 grid.add(reloadButton, {row, 0}, {1, 2});
308 row++;
309 grid.add(Label("Max History Size"), {row, 0}).add(maxHistorySize, {row, 1});
310 row++;
311 grid.add(Label("Infinite History Size"), {row, 0}).add(infiniteHistory, {row, 1});
312 row++;
313
314 group = {};
315 group.setLabel("Data");
316 group.addChild(grid);
317 }
318
319 void
321 {
322 if (reloadButton.wasClicked())
323 {
324 // Core segment mutex will be locked on commit.
325 segment.loadByObjectFinder();
326 rebuild = true;
327 }
328 if (infiniteHistory.hasValueChanged() || maxHistorySize.hasValueChanged())
329 {
330 segment.doLocked(
331 [this, &segment]()
332 {
333 segment.properties.maxHistorySize =
334 infiniteHistory.getValue() ? -1 : maxHistorySize.getValue();
335 if (segment.segmentPtr)
336 {
337 segment.segmentPtr->setMaxHistorySize(
338 long(segment.properties.maxHistorySize));
339 }
340 });
341 }
342 }
343
344 void
346 {
347 using namespace armarx::RemoteGui::Client;
348
349 showComboBox = {};
350 showOptionsIndex.clear();
351 segment.segmentPtr->forEachEntity(
352 [this](const wm::Entity& entity)
353 {
354 std::stringstream option;
355 option << entity.id().entityName << " (" << entity.id().providerSegmentName << ")";
356 showComboBox.addOption(option.str());
357 showOptionsIndex.push_back(entity.id());
358 });
359 if (showOptionsIndex.empty())
360 {
361 showComboBox.addOption("<none>");
362 }
363 showButton.setLabel("Visualize Object Class");
364
365 GridLayout grid;
366 int row = 0;
367 grid.add(showComboBox, {row, 0}, {1, 2});
368 row++;
369 grid.add(showButton, {row, 0}, {1, 2});
370 row++;
371
372 group = {};
373 group.setLabel("Visualization");
374 group.addChild(grid);
375 }
376
377 void
379 {
380 if (showButton.wasClicked())
381 {
382 const size_t index = static_cast<size_t>(showComboBox.getIndex());
383 if (/*index >= 0 &&*/ index < showOptionsIndex.size())
384 {
385 segment.visualizeClass(showOptionsIndex.at(index));
386 }
387 }
388 }
389
390} // namespace armarx::armem::server::obj::clazz
int Label(int n[], int size, int *curLabel, MiscLib::Vector< std::pair< int, size_t > > *labels)
Definition Bitmap.cpp:801
#define option(type, fn)
#define VAROUT(x)
Used to find objects in the ArmarX objects repository [1] (formerly [2]).
A known object ID of the form "Dataset/ClassName" or "Dataset/ClassName/InstanceName".
Definition ObjectID.h:11
Accessor for the object files.
Definition ObjectInfo.h:37
PackageFileLocation wavefrontObj() const
std::optional< simox::AxisAlignedBoundingBox > loadAABB() const
Load the AABB (axis-aligned bounding-box) from the bounding box JSON file.
PackageFileLocation urdf() const
std::optional< simox::OrientedBox< float > > loadOOBB() const
Load the OOBB (object-oriented bounding box) from the bounding box JSON file.
std::optional< std::vector< std::string > > loadSpokenNames() const
Load names to use when verbalizing an object name.
PackageFileLocation articulatedSdf() const
PackageFileLocation articulatedUrdf() const
PackageFileLocation sdf() const
PackageFileLocation meshWrl() const
ObjectID id() const
Return "dataset/name".
std::optional< std::vector< std::string > > loadRecognizedNames() const
Load names to use when matched when recognizing an object by name.
PackageFileLocation simoxXML() const
PackageFileLocation articulatedSimoxXML() const
std::string str(bool escapeDelimiters=true) const
Get a string representation of this memory ID.
Definition MemoryID.cpp:102
MemoryID withEntityName(const std::string &name) const
Definition MemoryID.cpp:425
std::string entityName
Definition MemoryID.h:53
std::string providerSegmentName
Definition MemoryID.h:52
Base class for all exceptions thrown by the armem library.
Definition ArMemError.h:19
Helps connecting a Memory server to the Ice interface.
void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string &prefix="") override
Definition Segment.cpp:39
void visualizeClass(const MemoryID &entityID, bool showAABB=true, bool showOOBB=true)
Definition Segment.cpp:147
arondto::ObjectClass objectClassFromInfo(const ObjectInfo &info)
Definition Segment.cpp:212
Segment(armem::server::MemoryToIceAdapter &iceMemory)
Definition Segment.cpp:26
auto doLocked(FunctionT &&function) const
Execute function under shared (read) lock.
SpecializedCoreSegment(MemoryToIceAdapter &iceMemory, const std::string &defaultCoreSegmentName="", aron::type::ObjectPtr coreSegmentAronType=nullptr, int defaultMaxHistorySize=10, const std::vector< PredictionEngine > &predictionEngines={})
A base class for aron exceptions.
Definition Exception.h:37
static DateTime Now()
Definition DateTime.cpp:51
DerivedT & pose(Eigen::Matrix4f const &pose)
Definition ElementOps.h:176
DerivedT & color(Color color)
Definition ElementOps.h:218
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
void fromAron(const arondto::MemoryID &dto, MemoryID &bo)
armarx::core::time::DateTime Time
void toAron(arondto::MemoryID &dto, const MemoryID &bo)
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
void addChildren(std::initializer_list< Widget > children)
Definition Widgets.cpp:101
GridLayout & add(Widget const &child, Pos pos, Span span=Span{1, 1})
Definition Widgets.cpp:438
A bundle of updates to be sent to the memory.
Definition Commit.h:90
EntityUpdate & add()
Definition Commit.cpp:80
std::vector< EntityUpdate > updates
The entity updates.
Definition Commit.h:97
An update of an entity for a specific point in time.
Definition Commit.h:26
armarx::RemoteGui::Client::CheckBox infiniteHistory
Definition Segment.h:74
armarx::RemoteGui::Client::GroupBox group
Definition Segment.h:70
armarx::RemoteGui::Client::IntSpinBox maxHistorySize
Definition Segment.h:73
armarx::RemoteGui::Client::Button reloadButton
Definition Segment.h:72
armarx::RemoteGui::Client::GroupBox group
Definition Segment.h:86
armarx::RemoteGui::Client::ComboBox showComboBox
Definition Segment.h:89
armarx::RemoteGui::Client::GroupBox group
Definition Segment.h:66
Box & size(Eigen::Vector3f const &s)
Definition Elements.h:52
void add(ElementT const &element)
Definition Layer.h:31
Object & file(std::string const &project, std::string const &filename)
Definition Elements.h:340
#define ARMARX_TRACE
Definition trace.h:77