|
In order to make a new type of data available in the memory system, you first need to create an ARON XML file. Please refer to Aron/CodeGeneration if you want to know how to do so.
Note: If you plan to extend an existing memory server, you can skip this step.
If your data should be stored in a new memory server, follow these steps:
Create a new component, let's say MyMemory
:
Then, extend the new component by the respective component plugin.
Add the include:
Make the component derive from the component plugin user:
Don't forget to add the respective library to your CMakeLists.txt
:
If the component already implements an ice interface, you have to add the memory server into face to it (otherwise, you will receive ‘no unique final overrider for 'virtual function ...’` errors by the compiler):
In this case, make sure RobotAPIInterfaces
is in the Ice dependencies of your ice library:
You can set the memory name of the memory server in the createPropertyDefinitions()
:
Note:
ReadWritePluginUser
implements the ice interface MemoryInterface
, which combines, among others, the ReadingMemoryInterface
and the WritingMemoryInterface
.ReadOnlyPluginUser
only implements the ReadingMemoryInterface
.workingMemory()
(of type armem::server::wm::Memory
) and an iceAdapter()
(armem::server::MemoryToIceAdapter
).That's it: Your component is now a memory server.
Wait, how does the new memory server know of my specially written ARON type?
Oh right, it doesn't. At least not yet. But this is easy to fix: We just have to add a core segment.
What on earth is a core segment?
A segment is a section of a memory (server) containing data of a specific type, i.e. they are homogeneous data containers (in contrast to heterogeneous, which would mean they contain different kinds of data) (see the Introduction).
There are two kinds of segments: core segments, and provider segments:
... what?
Just stick with me, you'll get used to it.
Okay ... but how does the memory add the ... core segment?
A fine question! Luckily, that's very simple. All we need is your ARON type, a name and the working memory data structure.
...
Okay, okay, I'll come to the code. Adding a core segment merely alters a local data structure (it is not an ice/network operation). Thus, we can do it in onInitComponent()
:
workingMemory()
is a function provided by the component plugin user (ReadWritePluginUser
or ReadOnlyPluginUser
) returning a reference to the working memory data of the type armem::server::wm::Memory
.addCoreSegment()
adds a core segment. It takes a name and (optionally) an ARON type."Data"
is the name of the core segment.armarx::mydata::arondto::MyData
is the C++ class generated from your MyData.xml
ARON XML description file.::toAronType()
creates a runtime type object describing the ARON type. This allows, e.g., the MemoryViewer
GUI to show the data in a suitable manner (e.g. a pose as an affine transformation instead of a 4x4 matrix).ObjectInstance.xml
located at RobotAPI/libraries/armem_objects/aron/ObjectInstance.xml
, the include would be:Note that you need to include the .h
file, not the .xml
. As the generated class is header-only, you do not need to link any libraries in your CMakeLists.txt
.
When you now start your new memory server and the MemoryNameSystem (MNS) (e.g. using the scenario ArMemCore in RobotAPI), and open the MemoryViewer gui plugin, you should see an entry for your memory (My
) and the core segment (Data
under My
).
That's it! You now have a memory server providing a place where your nice and interesting data can feel welcome, and where interested listeners would look to find it.
Next, we learn how to commit data to the memory, and query data from the memory.