The working memory holds data that is needed for online processing (e.g. localization results and object positions). It can be filled from memory snapshots and store the current data to a snapshot instance (stored in the LongTerm Memory).
The working memory is a SegmentedMemory, which means that the data is organized in segments. By default there are the following segments available:
ObjectInstances: This segment holds all object instances that the robot currently is aware of - e.g. objects that have been localized By default the following two fusion methods are instanciated for the ObjectInstances segment:
PriorAttributeEnrichmentFusion (This fusion method adds attributes from (prior? longterm?) knowledge whenever an entity is added)
AttributeReplacementFusion (Used when an entity is updated to copy all attributes to the newly localized entity instance)
ObjectClasses: All object classes that are currently of interest (e.g. an object localizer is currently searching for them) are stored here.
ObjectRelations: Semantic relations between objects (s. memoryx::Relation), e.g. "Cup" isOn "Table" with probability 0.7.
By default, an instance of ObjectLocalizationMemoryUpdater is created and registered. This updater automatically initiates (re-)localization of objects that have been requested, integrates new localization results with former ones and applies the objects' motion models to predict their pose between the localizations.
Configuration
Following properties are supported:
UseKalmanFilter (true): Switch fusion with Kalman Filter on/off
MatchThreshold (0): Threshold value of spatial proximity between observations to consider them belonging to the same instance (0..1)
MatchByClassName (true): Check for class equality when searching for corresponding instance
PublishUpdates (true): whether scene updates (ObjectCreated/Updated/Removed) should be published on IceStrom topic
UpdatesTopicName (WorkingMemoryUpdates): IceStorm topic name for scene updates
UsePriorMemory (true): whether PriorKnowledge should be used
PriorMemoryName (PriorKnowledge): PriorKnowledge component name
UseLongtermMemory (true): whether longterm memory should be used
LongtermMemoryName (LongtermMemory): LongtermMemory component name
For new objects, unique ID will be automatically generated and returned by addEntity() function. If you want to update the same object instance later, save this ID and use the updateEntity() function.
To iterate through all the object in the scene, use the following code:
EntityIdList ids = memoryPrx->getAllEntityIds();
for(EntityIdList::const_iterator it = ids.begin(); it != ids.end(); ++it)
When the pose of an object (or a robot hand) is needed, the localization is done by the WorkingMemory. To this end, the memory needs to be advised to localize the object, which we do via the ObjectMemoryObserver.
This code causes the memory to retrieve the desired object from the Prior Knowledge, contact the appropriate localizer, and automatically localize the object every 100 ms.
If the object has been localized at least once, its pose is available. It can be obtained from the ObjectMemoryObserver using the ChannelRef we got when we requested the object:
// several instances of the object have been found - iterate through the list
}
Simplified sequence diagram for the object localization with Working Memory and ObjectMemoryUpdater
Motion models
Every object instance that is being localized and held in the working memory is associated with a motion model. The default motion model for each object is stored in the PriorKnowledge and can be set via the PriorKnowledgeEditor gui. For most objects, the static model is used which assumes that the object just stays where it is. The robot hands have their own motion model which updates their pose according to the kinematic model while they are not being re-localized.
Another motion model that may be usefull sometimes is the MotionModelAttachedToOtherObject. This model can be used to attach the object to another object, e g. a robot hand when it has been grasped. It's predicted pose is then update by keeping it constant with relation to the object that it has been attached to.
To change the motion model e.g. to the one for attaching the object to a hand, do the following:
MemoryX supports binary, probabilistic relations between object instances. Please note, that all relations are unidirectional, i.e. not symmetric. Symmetry can be modeled explicitly by adding two relations, one per direction. E.g. "Cup is near the Plate" would be represented as isNear(Cup, Plate) and isNear(Plate, Cup).
The API for working with relations is pretty similar to objects API.
ARMARX_ERROR << "SnapshotName parameter must be specified!" << flush;
// ...
}
Subscribing for scene updates
Scene updates are published on an IceStorm topic, default name is "WorkingMemoryUpdates". To process them, implement WorkingMemoryObserverInterface and subscribe to the topic as usual.
NOTE: The subscription to the topic will be established after onConnectComponent().