ArmarX Object Notation (ARON) / Interpretable Data Format (IDF)
See also

ARON (ArmarX Object Notation) is the ArmarX implementation of variants which can be transferred over the network via ZeroC Ice. Further, ARON is the data representation used in the ArmarX Memory System. We distinguish between:

  • type specification vs. data information
  • data transfer object (in the following called "ARON DTO") vs. its corresponding C++ wrapper (in the following called "ARON object"). The DTO specification is done in ice so that every ARON object can be transferred via ice.

ARON Type specification

An ARON type specification defines the static type for an ARON data DTO or an ARON data object. It does not contain any data (e.g. an ARON type list only knows the accepted type, not the list members). Since ARON supports maybe types (raw ptr, smart ptr, optional), every ARON type DTO contains a special member. It can only consist of the following types and information (ARONVariant means any Type):

Object { // dto called armarx::aron::type::dto::AronObject
string name;
AronVariant extends;
map<string, AronVariant> memberTypes;
}
Dict { // dto called armarx::aron::type::dto::Dict
AronVariant acceptedType;
}
List { // dto called armarx::aron::type::dto::List
AronVariant acceptedType;
}
Pair { // ...
AronVariant acceptedType1;
AronVariant acceptedType2;
}
Tuple {
vector<AronVariant> acceptedTypes;
}
IntEnum {
string name;
map<string, int> acceptedValues;
}
NDArray {
int ndim;
type type; // in [uint8, int8, uint16, int16, uint32, int32, float32, float64]
}
int rows, cols;
type type; // in [int16, int32, int64, float32, float64]
}
type type; // in [float32, float64]
}
}
}
}
Image {
pixelType type; // in [rgb24, depth32]
}
voxelType type; // in [PointXYZ, PointXYZI, PointXYZL, PointXYZRGB, PointXYZRGBA, PointXYZRGBL, PointXYZHSV]
}
Int { // dto called armarx::aron::type::dto::AronInt
}
Long { // dto called armarx::aron::type::dto::AronLong
}
Float { // dto called armarx::aron::type::dto::AronFloat
}
Double { // dto called armarx::aron::type::dto::AronDouble
}
String { // dto called armarx::aron::type::dto::AronString
}
Bool { // dto called armarx::aron::type::dto::AronBool
}
Time { // dto called armarx::aron::type::dto::AronTime
}

ARON Data specification

ARON data objects and ARON data DTOs are similar structured to type objects and type DTOs. However, there are fewer classes for data objects and data DTOs. ARON data is completely decoupled from the static types and contains the data members (e.g. an aron data list only contains the list members (as ARONVariants) and not the accepted type):

Dict { // dto called armarx::aron::data::dto::Dict
map<string, AronVariant> members;
}
List { // dto called armarx::aron::data::dto::List
vector<AronVariant> elements;
}
NDArray { // ...
vector<int> shape;
string type;
vector<byte> data;
}
Int { // dto called armarx::aron::data::dto::AronInt
int value;
}
Long { // dto called armarx::aron::data::dto::AronLong
long value;
}
Float { // dto called armarx::aron::data::dto::AronFloat
float value;
}
Double { // dto called armarx::aron::data::dto::AronDouble
double value;
}
String { // dto called armarx::aron::data::dto::AronString
string value;
}
Bool { // dto called armarx::aron::data::dto::AronBool
bool value;
}
Note
Note that every ARON data object or DTO can be nullptr! The reason is that if the type supports maybe types and a member is, for example, optional, the data must support maybetype as well. If a generated ARON class (We come to the code generation later) has an optional member, this member will be translated into a NULL ARON object and DTO.

Connection of ARON data and ARON type

ARON data contains fewer classes than ARON type. Because ARON data objects and DTOs do not check the type of the members (they can be any aron data (ARONVariant)), we can only validate an aron data object or DTO if we have the type information. The following mapping describes, how data and types correspond.

ARON Type ARON Data
Object Dict
Dict Dict
List List
Pair List
Tuple List
NDArray NDArray
Matrix NDArray
Quaternion NDArray
Position NDArray
Orientation NDArray
Pose NDArray
Image NDArray
PointCloud NDArray
IntEnum Int
Int Int
Long Long
Float Float
Double Double
String String
Bool Bool
Time Long

If no type object or DTO is available, we can at least derive some information from the data object (e.g. "it is a data dict, so the type cant be list").

To differ between data and type makes it easier to work with these Variants. In most cases, the type information is not relevant. Then you only have to check for the data type.

ARON Data and Type Objects

As already mentioned, we implemented wrapper classes around the DTO. These classes offer convenience methods and conversions and make lots things easier when working directly with ARON. These classes can be found at aron/core/{data,type}/variant/Variant.h.

The ARON objects have more or less the same structure as the DTOs (see above). Everything is stored as a std::shared_ptr (e.g. members, elements, acceptedTypes, ...). If you want to implement a method which takes any ARON data object as input, you can use the base class of every ARON data object:

void myFancyMethod(const armarx::aron::data::VariantPtr& variant);

If you want to check, what a variant really is, you can use the descriptor of the object:

armarx::aron::data::VariantPtr variant; // <-- the variant
auto desc = variant->getDescriptor();
switch(desc)
{
case armarx::aron::data::Descriptor::eDict: ...
case armarx::aron::data::Descriptor::eList: ...
...
}

If you have a DTO, you do not know the exact type, but you want to have a ARON object you can make use of the static construction methods:

armarx::aron::data::dto::GenericData dto; // <-- the DTO variant

If you know the type, you can use the constructor the specific ARON object.

Example to Create an ARON Data Dict from Scratch

Goal: Have an ARON dict with a list as member "the_list" and some values in it. Then echo the members and their descriptor as a string.

using namespace armarx;
// setup aron object
auto dict = std::make_shared<aron::data::Dict>();
{
auto list = std::make_shared<aron::data::List>();
for (unsigned int i = 0; i < 10; ++i)
{
list->addElement(std::make_shared<aron::data::Int>(i));
}
dict->addElement("the_list", list);
}
// echo
auto listVariant = dict->getElement("the_list"); // will return a aron::data::VariantPtr
auto list = aron::data::List::DynamicCastAndCheck(listVariant); // cast and check whether the cast was successful
for (const auto& intVar : list->getElements())
{
std::cout << "The value is: " << i->getValue() << std::endl;
std::cout << "The descriptor is: " << aron::data::defaultconversion::string::Descriptor2String.at(i->getDescriptor()) << std::endl;
}

Please note that we might add more methods or make the current ones more flexible (e.g. such as nlohmann::json).

Lessons Learned

  • There is a difference between ARON data and ARON type
  • There is a difference between ARON objects and ARON DTOs
  • How are ARON DTOs structured
  • How do ARON data and ARON types correspond
  • How to use the ARON objects
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:918
armarx::VariantType::List
const VariantContainerType List
Definition: SingleTypeVariantList.h:191
GfxTL::Orientation
ScalarT Orientation(const VectorXD< 2, ScalarT > &p1, const VectorXD< 2, ScalarT > &p2, const VectorXD< 2, ScalarT > &c)
Definition: Orientation.h:9
armarx::aron::data::Variant::FromAronDTO
static VariantPtr FromAronDTO(const data::dto::GenericDataPtr &, const Path &=Path())
create a variant from a dto object
Definition: Variant.cpp:39
armarx::navigation::core::Pose
Eigen::Isometry3f Pose
Definition: basic_types.h:31
list
list(APPEND SOURCES ${QT_RESOURCES}) set(COMPONENT_LIBS ArmarXGui ArmarXCoreObservers ArmarXCoreEigen3Variants PlotterController $
Definition: CMakeLists.txt:49
armarx::aron::data::defaultconversion::string::Descriptor2String
const std::map< data::Descriptor, std::string > Descriptor2String
Definition: Descriptor.h:224
armarx::VariantType::Bool
const VariantTypeId Bool
Definition: Variant.h:915
armarx::aron::data::detail::SpecializedVariantBase< data::dto::List, List >::DynamicCastAndCheck
static PointerType DynamicCastAndCheck(const VariantPtr &n)
Definition: SpecializedVariant.h:135
armarx::VariantType::Quaternion
const VariantTypeId Quaternion
Definition: Pose.h:39
armarx::aron::data::VariantPtr
std::shared_ptr< Variant > VariantPtr
Definition: forward_declarations.h:11
armarx::VariantType::Double
const VariantTypeId Double
Definition: Variant.h:919
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
armarx::VariantType::Long
const VariantTypeId Long
Definition: Variant.h:917
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
PointCloud
Definition: PointCloud.h:69
armarx::VariantType::Int
const VariantTypeId Int
Definition: Variant.h:916
Eigen::Matrix
Definition: EigenForwardDeclarations.h:27
cxxopts::String
std::string String
Definition: cxxopts.hpp:209
armarx::navigation::core::Position
Eigen::Vector3f Position
Definition: basic_types.h:36
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28