MemoryX HowTos

MemoryX Framework: How to create a Scene

Starting MongoDB

Before importing scenes into MemoryX it is required to start MongoDB:

Note
Using the armarx command without prefix assumes that either the ArmarX python scripts package is installed or ${ArmarXCore_DIR}/build/bin is in your $PATH variable.
armarx memory start

If an error occurs during the execution of this script follow the given advice and run

armarx memory repair

Overview

Currently, three different importers are available in Memoryx:

  • PriorKnowledgeImporter
  • SimoxSceneImporter
  • XMLSceneImporter

Prior Knowledge Importer

Use the memoryx::PriorKnowledgeImporter if you want to import OpenInventor (IV) models into a PriorKnowledge segment of MemoryX. It works by scanning a specified directory and importing all found *.iv and *.wrl files.

Each object is stored in MongoDB as

  • IV file
  • Texture file
  • Simox ManipualtionObject XML file

The object name with which the object can be retrieved from memory is determined by stripping .iv or .wrl from the filenames to be imported.

For importing IV files into MemoryX take a look at the scenario MemoryX/scenarios/PriorKnowledgeImporter/. This scenario starts all required components to import files from a single directory. The following component properties control from where the files are imported and into which part of the memory:

# PriorKnowledge
MemoryX.PriorKnowledge.ClassCollections = memdb.Prior_Objects # name of PriorKnowledge collection in MongoDB
MemoryX.PriorKnowledge.RelationCollections = memdb.Prior_classrel # name of ClassRelations collection in MongoDB
# PriorKnowledgeImporter
MemoryX.PriorKnowledgeImporter.FilesDirectory = /path/to/files/ # name of directory from where to import files
MemoryX.PriorKnowledgeImporter.FilesDbName = memdb # name of the database to use in MongoDB
MemoryX.PriorKnowledgeImporter.TaskName = ImportFiles # task to perfrom (Importfiles is for importing files)

Simox Scene Importer

For importing complete scenes (including PriorKnowledge) the SimoxSceneImporter should be used. The import of a Simox scene description XML includes the follwowing steps:

  • import all found objects into PriorKnowledge
  • clear current WorkingMemory contents
  • load found objects into WorkingMemory at the locations specified in the XML file
  • create a snapshot of the new WorkingMemory content
Note
Please beware that an existing PriorKnowledge object will be updated with the information found in the Simox scene description.

An example on how to import Simox scenes can be found in the scenario MemoryX/scenarios/SimoxSceneImporter/. All required components for importing Simox scenes are started by this scenario. To adapt the import process to your needs take a look at the following component Properties:

# PriorKnowledge
MemoryX.PriorKnowledge.ClassCollections = memdb.Prior_Objects # name of PriorKnowledge collection in MongoDB
# SimoxSceneImporter
MemoryX.SimoxSceneImporter.SnapshotName = SceneName # name of the snapshot to be stored (Snapshot_ will be prepended)
MemoryX.SimoxSceneImporter.FilesDbName = memdb # name of the database to use in MongoDB
MemoryX.SimoxSceneImporter.SceneFile = /path/to/scene.xml # path to the Simox scene description file to import

XML Scene Importer

The XMLSceneImporter is usde to import scene descriptions which were exported from Blender (how does this export work?). During import, all found entities referenced in the file will be added to the WorkingMemory (objectInstances memory segment) but no objects will be added to PriorKnowledge. After WorkingMemory has been filled with object instances, a snapshot is generated.

The scenario MemoryX/scenarios/XMLSceneImporter/ starts all required components for importing Blender scene descriptions. It can be adjusted by tuning the following component Properties:

MemoryX.PriorKnowledge.ClassCollections = memdb.Prior_Objects # name of PriorKnowledge collection in MongoDB
MemoryX.XMLSceneImporter.SceneFile = /path/to/scene.xml # path to Blender scene file to import
MemoryX.XMLSceneImporter.SnapshotName = Snapshot_SceneImport # name of the snapshot to be stored (should start with "Snapshot_")
MemoryX.XMLSceneImporter.TargetLengthUnit = MM # unit specification to use while importing the scene

The following files which can be imported with this method can be found in MemoryX/data/MemoryX:

H2T-Kitchen.xml H2T-Kitchen-open-cupboards.xml H2T-Kitchen-open-fridge.xml H2T-Kitchen-alternate-orientation.xml MobileKitchen.xml

How to inspect the current content of the database with RobotMongo

An easy-to-use GUI for accessing and querying MongoDB is RoboMongo.

RoboMongo connects to an MongoDB instance and allows you to inspect and edit the current conent of the database.

The Robomongo tool

How to request localization of an object and retrieve it from MemoryX

How to retrieve a ChannelRef from an object name and trigger continuous object recognition every 30 milliseconds.

#include <MemoryX/interface/observers/ObjectMemoryObserverInterface.h>
// this should be defined in a statechart context
memoryx::ObjectMemoryObserverInterfacePrx objectMemoryObserver = getProxy<memoryx::ObjectMemoryObserverInterfacePrx>(getProperty<std::string>("ObjectMemoryObserverName").getValue());
// this is the code inside the statechart
std::string objectName = getInput<std::string>(inputName);
// this retrieves a pointer to the localization query
ChannelRefBasePtr objectClassChannel = objectMemoryObserver->requestObjectClassRepeated(objectName, 30, armarx::DEFAULT_VIEWTARGET_PRIORITY);
ChannelRefBasePtr objectInstanceChannel;
do
{
objectInstanceChannel = objectMemoryObserver->getFirstObjectInstance(objectClassChannel);
usleep(10000);
}while(!objectInstanceChannel);

The objectInstanceChannel now contains the information about the instance of the object and queried as shown below.

How to retrieve position and orientation from a ChannelRef

ChannelRefPtr objectInstanceChannel = getInput<ChannelRef>("objectInstanceChannel");
FramedPositionPtr objectPosition = objectInstanceChannel->get<FramedPosition>("position");
objectPosition->toEigen();
FramedOrientationPtr objectOrientation = objectInstanceChannel->get<FramedOrientation>("orientation");
objectOrientation->toEigen();

How to use a ChannelRef to install a condition:

ChannelRefPtr markerChannel = getInput<ChannelRef>("markerChannel");
Literal markerLost(*markerChannel->getDataFieldIdentifier("existenceCertainty"), "smaller", Literal::createParameterList(minRecognitionLikelihood));
installCondition( markerLost, createEvent<EvFailure>());

Needed changes in your CMakeLists.txt

Required code in toplevel CMakeLists.txt

depends_on_armarx_package(MemoryX)

Required libraries to link to your (statechart) library

MemoryXInterfaces
MemoryXCore
MemoryXMemoryTypes

How to create a new database

Databases are automatically created on the fly depending on the configuration of the components you are starting in your scenario. If you specify a collection in the LongtermMemory config file that does not exists, the database and the collection will be created automatically. With the Collections config parameters in the PriorKnowledge configuration it is also possible to use multiple databases at once since the database and collection name need to be specified for each collection (e.g. memdb.ObjectClasses).

If you want to create and use a new empty database, your CMakeLists.txt hase to contain following lines:

set(SCENARIO_CONFIGS
        config/LongtermMemory.cfg
)

Furthermore you have to insert following line into the file config/LongtermMemory.cfg:

MemoryX.LongtermMemory.DatabaseName = new_db

where "new_db" has to be replaced with the name of the database you want to create.

How to access object and mesh files

MemoryX provides cosistent mechanisms to store data files in mongodb (see GridFS files and file reference attributes for details). Since some APIs need data files to be locally present (i.e. accessible via the file system), MemoryX offers methods to download/cache these data files to a local directory on your host. The default cache directory is

~/.armarx/mongo/.cache/files

On request the files are cached to that directory and can be accessed via standard file I/O operations. You can manually inspect the content of this directory if you need to know which files are used. Note, that any changes that are made here will be overwritten automatically whenever the file is accessed through MemoryX. In addition, the GridFS File Editor Gui Plugin can be used to inspect and to edit the files that are stored in the database.

How to lock a memory segment over several calls

It is possible to obtain a lock on the memory for any other access to prohibit any other changes (and access at all) to the memory. For this it is needed to call the function MemoryInterface::lockSegment() (this works only on remote calls!). After this, the segment is locked for any reading or writing call unless the specific token received from lockSegment() is passed in (the functions will wait until the segment is unlocked again). This lock prevails until the return value of lockSegment() goes out of scope or unlockSegment() is called. Long story short, here is an easy example:

{
MemoryInterfacePrx segment = getPriorKnowledge()->getObjectClassesSegment();
::memoryx::SegmentLockBasePtr lock = segment->lockSegment();
::memoryx::EntityBaseList entities = segment->getAllEntities(MEMORYX_TOKEN(lock));
::memoryx::ObjectClassBasePtr newObj = new ::memoryx::ObjectClass();
segment->addEntity(newObj, MEMORYX_TOKEN(lock));
} // lock goes out of scope -> segment is unlocked

An automatic keepAlive makes certain that the segment is also unlocked if your program crashes.

files
Use of this software is granted under one of the following two to be chosen freely by the user Boost Software License Version Marcin Kalicinski Permission is hereby free of to any person or organization obtaining a copy of the software and accompanying documentation covered by this and transmit the and to prepare derivative works of the and to permit third parties to whom the Software is furnished to do all subject to the including the above license this restriction and the following must be included in all copies of the in whole or in and all derivative works of the unless such copies or derivative works are solely in the form of machine executable object code generated by a source language processor THE SOFTWARE IS PROVIDED AS WITHOUT WARRANTY OF ANY EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF FITNESS FOR A PARTICULAR TITLE AND NON INFRINGEMENT IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN TORT OR ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE The MIT Marcin Kalicinski Permission is hereby free of to any person obtaining a copy of this software and associated documentation files(the "Software")
armarx::ChannelRefPtr
IceInternal::Handle< ChannelRef > ChannelRefPtr
Definition: ChannelRef.h:41
use
Use of this software is granted under one of the following two to be chosen freely by the user Boost Software License Version Marcin Kalicinski Permission is hereby free of to any person or organization obtaining a copy of the software and accompanying documentation covered by this and transmit the and to prepare derivative works of the and to permit third parties to whom the Software is furnished to do all subject to the including the above license this restriction and the following must be included in all copies of the in whole or in and all derivative works of the unless such copies or derivative works are solely in the form of machine executable object code generated by a source language processor THE SOFTWARE IS PROVIDED AS WITHOUT WARRANTY OF ANY EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF FITNESS FOR A PARTICULAR TITLE AND NON INFRINGEMENT IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN TORT OR ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE The MIT Marcin Kalicinski Permission is hereby free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
Definition: license.txt:39
MemoryXCoreObjectFactories.h
armarx::FramedPositionPtr
IceInternal::Handle< FramedPosition > FramedPositionPtr
Definition: FramedPose.h:134
armarx::control::common::getValue
T getValue(nlohmann::json &userConfig, nlohmann::json &defaultConfig, const std::string &entryName)
Definition: utils.h:71
armarx::FramedOrientationPtr
IceInternal::Handle< FramedOrientation > FramedOrientationPtr
Definition: FramedPose.h:191
armarx::VariantType::FramedOrientation
const VariantTypeId FramedOrientation
Definition: FramedPose.h:40
MEMORYX_TOKEN
#define MEMORYX_TOKEN(lock)
Definition: SegmentUtilImplementations.h:31
armarx::VariantType::FramedPosition
const VariantTypeId FramedPosition
Definition: FramedPose.h:39
MM
#define MM
Definition: Random.cpp:15
ChannelRef.h