10 #include <sys/inotify.h>
11 #include <sys/types.h>
14 #include <SimoxUtility/algorithm/string/string_tools.h>
15 #include <VirtualRobot/Grasping/Grasp.h>
16 #include <VirtualRobot/Grasping/GraspSet.h>
17 #include <VirtualRobot/ManipulationObject.h>
18 #include <VirtualRobot/VirtualRobot.h>
19 #include <VirtualRobot/XML/ObjectIO.h>
34 #include <RobotAPI/libraries/armem_grasping/aron/KnownGraspCandidate.aron.generated.h>
36 #include <linux/limits.h>
43 Base(iceMemory, PROVIDER_SEGMENT_NAME, CORE_SEGMENT_NAME)
57 std::optional<arondto::KnownGraspInfo>
58 KnownGraspProviderSegment::knownGraspInfoFromObjectInfo(
const ObjectInfo& info)
60 return knownGraspInfoFromFile(GraspFileInfo::FromObjectInfo(info));
63 std::optional<arondto::KnownGraspInfo>
64 KnownGraspProviderSegment::knownGraspInfoFromFile(
const GraspFileInfo& graspFileInfo)
67 const std::filesystem::path graspFilePath = graspFileInfo.fileLocInfo.absolutePath;
68 if (not std::filesystem::is_regular_file(graspFilePath))
76 const std::string objectClassName = graspFileInfo.objectId.className();
78 auto manipulationObject = VirtualRobot::ObjectIO::loadManipulationObject(graspFilePath);
80 if (manipulationObject ==
nullptr)
86 arondto::KnownGraspInfo
ret;
87 ret.correspondingObject.memoryName =
"Object";
88 ret.correspondingObject.coreSegmentName =
"Class";
89 ret.correspondingObject.providerSegmentName =
"PriorKnowledgeData";
90 ret.correspondingObject.entityName = graspFileInfo.objectId.str();
91 ret.xml.package = graspFileInfo.fileLocInfo.package;
92 ret.xml.path = graspFileInfo.fileLocInfo.relativePath;
94 for (
const VirtualRobot::GraspSetPtr& graspSet : manipulationObject->getAllGraspSets())
98 arondto::KnownGraspSet retGraspSet;
100 retGraspSet.name = graspSet->getName();
104 retGraspSet.endeffector = graspSet->getEndEffector();
106 VirtualRobot::GraspSetPtr preGraspSet = [&graspSet]()
108 std::vector<VirtualRobot::GraspPtr> preGrasps;
109 for (
const auto& grasp : graspSet->getGrasps())
114 preGrasps.emplace_back(grasp);
121 VirtualRobot::GraspSetPtr preGraspSet = graspSet->clone();
122 preGraspSet->removeAllGrasps();
123 for (
const auto& preGrasp : preGrasps)
125 preGraspSet->addGrasp(preGrasp);
135 for (
const auto& preGrasp : preGraspSet->getGrasps())
137 graspSet->removeGrasp(preGrasp);
141 for (
const VirtualRobot::GraspPtr& grasp : graspSet->getGrasps())
145 arondto::KnownGrasp retGrasp;
147 retGrasp.name = grasp->getName();
148 retGrasp.quality = grasp->getQuality();
149 retGrasp.creator = grasp->getCreationMethod();
150 retGrasp.pose = grasp->getTransformation();
151 retGrasp.prepose.reset();
155 const std::string prePoseName = retGrasp.name + PREPOSE_SUFFIX;
157 ARMARX_DEBUG <<
"Checking for prepose '" << prePoseName <<
"' ...";
159 if (preGraspSet->hasGrasp(prePoseName))
162 preGraspSet->getGrasp(prePoseName)->getTransformation();
165 preGraspSet->removeGrasp(preGraspSet->getGrasp(prePoseName));
168 ARMARX_DEBUG <<
"Found prepose `" + prePoseName +
"` for grasp '"
169 << retGrasp.name <<
"' in set '" << retGraspSet.name
170 <<
"' for obj '" << objectClassName <<
"' with pose \n"
171 << retGrasp.prepose.value();
179 const std::string prePoseName =
180 retGrasp.name.substr(
181 0, retGrasp.name.size() - std::strlen(GRASP_OPTIONAL_SUFFIX)) +
184 ARMARX_DEBUG <<
"Checking for prepose '" << prePoseName <<
"' ...";
186 if (preGraspSet->hasGrasp(prePoseName))
189 preGraspSet->getGrasp(prePoseName)->getTransformation();
192 preGraspSet->removeGrasp(preGraspSet->getGrasp(prePoseName));
194 ARMARX_DEBUG <<
"Found prepose `" + prePoseName +
"` for grasp '"
195 << retGrasp.name <<
"' in set '" << retGraspSet.name
196 <<
"' for obj '" << objectClassName <<
"' with pose \n"
197 << retGrasp.prepose.value();
201 ARMARX_DEBUG <<
"Found grasp '" << retGrasp.name <<
"' in set '"
202 << retGraspSet.name <<
"' for obj '" << objectClassName
206 retGraspSet.grasps.push_back(retGrasp);
210 if (preGraspSet->getSize() > 0)
213 <<
" preposes in the grasp set '" << retGraspSet.name
214 <<
"' for obj '" << objectClassName
215 <<
"' that do not have a corresponding grasp!";
216 for (
const auto& preGrasp : preGraspSet->getGrasps())
222 ARMARX_CHECK(
ret.graspSets.count(retGraspSet.robot +
"/" + retGraspSet.name) == 0)
223 <<
"The grasp set `" << retGraspSet.robot +
"/" + retGraspSet.name
224 <<
"` was defined twice!";
226 ret.graspSets[retGraspSet.robot +
"/" + retGraspSet.name] = retGraspSet;
232 ARMARX_WARNING << graspFilePath <<
" is not a manipulation object!"
239 KnownGraspProviderSegment::loadMemory()
242 ObjectFinder objectFinder;
245 const bool checkPaths =
false;
246 std::vector<ObjectInfo> infos = objectFinder.findAllObjects(checkPaths);
250 ARMARX_INFO <<
"Checking up to " << infos.size() <<
" object classes from '"
251 << objectFinder.getPackageName() <<
"' ...";
254 for (ObjectInfo& info : infos)
257 if (
auto knownGraspCandidate = knownGraspInfoFromObjectInfo(info); knownGraspCandidate)
259 EntityUpdate&
update = commit.add();
260 update.entityID = providerID.withEntityName(info.
id().
str());
264 update.instancesData = {knownGraspCandidate->toAron()};
267 for (
const auto& gs : knownGraspCandidate->graspSets)
270 for (
const auto& grasp : gs.second.grasps)
278 <<
" grasp candidates from object classes from '"
279 << objectFinder.getPackageName() <<
"'.";
281 if (!result.allSuccess())
283 ARMARX_WARNING <<
"Got errors for commit: " << result.allErrorMessages();
288 KnownGraspProviderSegment::installFileWatcher()
291 const ObjectFinder objectFinder;
292 const std::vector<ObjectInfo> infos = objectFinder.findAllObjects(
false);
294 const bool autoReloadSceneSnapshotsOnFileChange =
true;
296 if (autoReloadSceneSnapshotsOnFileChange)
303 inotifyFd = inotify_init();
310 std::map<int, GraspFileInfo> wds;
313 for (
const auto& info : infos)
315 const auto graspFileInfo = GraspFileInfo::FromObjectInfo(info);
317 if (std::filesystem::exists(graspFileInfo.fileLocInfo.absolutePath))
319 auto wd = inotify_add_watch(
320 inotifyFd, graspFileInfo.fileLocInfo.absolutePath.c_str(), IN_MODIFY);
324 << graspFileInfo.fileLocInfo.absolutePath <<
"` failed.";
328 << graspFileInfo.fileLocInfo.absolutePath <<
"` added.";
329 wds.emplace(wd, graspFileInfo);
333 ARMARX_INFO <<
"Set up " << wds.size() <<
" inotify events to watch for file changes.";
335 fileWatcherTask =
new SimpleRunningTask<>(
336 [
this, inotifyFd, wds]()
338 ObjectFinder objectFinder;
340 constexpr std::size_t BUF_LEN = (10 * (
sizeof(inotify_event) + NAME_MAX + 1));
347 numRead =
read(inotifyFd, buf, BUF_LEN);
360 for (
char* p = buf; p < buf + numRead;)
362 auto*
event =
reinterpret_cast<inotify_event*
>(p);
364 const auto& graspFileInfo = wds.at(event->wd);
366 <<
VAROUT(graspFileInfo.fileLocInfo.absolutePath);
368 ARMARX_INFO <<
"Reloading file for object `" << graspFileInfo.objectId <<
"`.";
370 p +=
sizeof(
struct inotify_event) + event->len;
372 const bool lockMemory =
true;
378 objectFinder.getPackageName());
383 if (
auto knownGraspCandidate =
384 knownGraspInfoFromFile(graspFileInfo);
387 EntityUpdate&
update = commit.add();
389 providerID.withEntityName(graspFileInfo.objectId.str());
394 update.instancesData = {knownGraspCandidate->toAron()};
397 <<
VAROUT(knownGraspCandidate->graspSets.size());
398 for (
const auto& gs : knownGraspCandidate->graspSets)
401 for (
const auto& grasp : gs.second.grasps)
410 if (not commit.updates.empty())
415 if (not result.allSuccess())
418 << result.allErrorMessages();
426 fileWatcherTask->start();