class  ChannelRef
 The ChannelRef class is a reference to a channel on an Observer. It is used to access data directly from a channel or to be passed to function as an identifier for a channel. More...
class  DatafieldRef
 The DatafieldRef class is similar to the ChannelRef, but points to a specific Datafield instead of to a complete channel. It can be used to query (getDataField()) the data of the datafield from the Observer. More...
class  FramedDirection
 FramedDirection is a 3 dimensional direction vector with a reference frame. The reference frame can be used to change the coordinate system to which the vector relates. The difference to a FramedPosition is, that on frame changing only the orientation of the vector is changed. The length of the vector remains unchanged. This class is usefull e.g. for forces and tcp velocities. More...
class  FramedOrientation
 The FramedOrientation class. More...
class  FramedPose
 The FramedPose class. More...
class  FramedPosition
 The FramedPosition class. More...
class  LinkedDirection
 The LinkedDirection class. More...
class  LinkedPose
 The LinkedPose class. More...
class  MatrixDouble
 The MatrixDouble class. More...
class  MatrixFloat
 The MatrixFloat class. More...
class  Pose
 The Pose class. More...
class  Quaternion
 The Quaternion class. More...
class  SingleTypeVariantList
 The SingleTypeVariantList class is a subclass of VariantContainer and is comparable to a std::vector<T> containing values of type T. More...
class  SingleVariant
 The SingleVariant class is required to store single Variant instances in VariantContainer subclasses. More...
class  StringValueMap
 The StringValueMap class is a subclass of VariantContainer and is comparable to a std::map<std::string, T> containing values of type T. More...
class  TimestampVariant
class  Trajectory
 The Trajectory class represents n-dimensional sampled trajectories. More...
class  Variant
 The Variant class is described here: Variants. More...
class  VariantContainer
 VariantContainer is the base class of all other Variant container classes. More...
class  Vector2
 The Vector2 class. More...
class  Vector3
 The Vector3 class. More...
class  DiscreteProbability
 The DiscreteProbability class. More...
class  GaussianMixtureDistribution
 The GaussianMixtureDistribution class. More...
class  IsotropicNormalDistribution
 The IsotropicNormalDistribution class. More...
class  MultivariateNormalDistribution
 The MultivariateNormalDistribution class. More...
class  UnivariateNormalDistribution
 The UnivariateNormalDistribution class. More...

Detailed Description

Variants provide a mechanism to store several types of data in one construct and send them via Ice. The Variant class offers a unified interface for storing and accessing values of several data types. It is one of the essential data types of ArmarX and can be used in Ice communication. Variants can be extended and several Variant-based implementations of simple or complex data types like 6D poses are available in ArmarX.

Complex data types in the variant context are all that are not int, float, bool, double or string.

Basic Variant Usage

Variants can store instances of all classes that implement the VariantDataClass Ice interface. For the basic data types int, bool, float, double and std::string there are three main ways for creating a Variant.

In the following code three int-Variant instances are created using the different ways of instantiation:

Variant varInt;
Variant varInt(2);
Variant varInt;

This works analogously for the other basic data types. The setting of complex datatypes work similarly:

Variant varComplex(new TestComplexFloat(1, 2));
The TestComplexFloat is from the HowTo How to Create Custom Variant Types.

The stored values can be retrieved using the respective getter methods:

int value = varInt.getInt();

Or for complex types:

BOOST_CHECK(varComplex.getType() == VariantType::TestComplexFloat);
BOOST_CHECK(varComplex.get<TestComplexFloat>()->getReal() == 1);
BOOST_CHECK(varComplex.get<TestComplexFloat>()->getImag() == 2);

Note that after assigning a value to a variant and therefore after initially determining the Variant's type, changing the type is not possible anymore. Any assignment of data of a different than the set type will result in a LocalException.

There exist several implementations of Variant-types apart from the elementary ones:

List of all Variants: Variant Group

There are further classes that realize flexible containers of Variant-values, which are Variants themselves:

These containers are needed for the same reason as the Variant themselves: We need to be able to send different data via the same Ice interface. Since Ice interfaces always have a specific type, we need these classes with a common base class (VariantDataClass and VariantContainerBase).

Take a look at How to Create Custom Variant Types if you want to implement your own specialized Variant classes.

Serialization of Variants as JSON

It is easy to serialize a Variant into a JSON format. Every Variant type has this feature built in. You only need the armarx::JSONObject for the serialization and deserialization:

// Needed for deserialization - the communicator can be retrieved
// in any ManagedIceObject with getCommunicator()
// The next line is already done in a standard ArmarX app.
JSONObjectPtr jsonSerialize(new JSONObject(iceCommunicator));
// create Variant - every variant data type can be passed to the constructor
VariantPtr var = new Variant(3.0f);
jsonSerialize->setVariant("value", var); // key and value
std::string prettyJSONstring = jsonSerialize->asString(true); // true -> pretty JSON
// Now create the variant back from the string
JSONObjectPtr jsonDeserialize(new JSONObject(iceCommunicator));
jsonDeserialize->fromString(prettyJSONstring); // parse the JSON string
ARMARX_INFO << prettyJSONstring;
VariantPtr newVariant = jsonDeserialize->getVariant("value");
ARMARX_INFO << "float value: " << newVariant->getFloat();

The JSON then looks as follows:

   "value" : {
      "typeName" : "::armarx::FloatVariantData",
      "value" : 3.0
IceInternal::Handle< Variant > VariantPtr
Definition: Variant.h:42
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
IceInternal::Handle< JSONObject > JSONObjectPtr
Definition: JSONObject.h:34
Definition: Logging.h:174
static void RegisterKnownObjectFactoriesWithIce(const Ice::CommunicatorPtr &ic)
Registers all object factories that are known with Ice.
Definition: ArmarXManager.cpp:1204