As already mention in the introduction, aron supports code generation in order to create a C++ (other languages also possible) class with plain C++ members which you can use for convenience. Further, the generated class offers methods to convert itself to an Aron object and to set the members from an Aron object. Code generation only makes sense for Aron data, however we need an Aron type specification in order to generate the class.
In the following we will describe how to specify Aron types in XML and how the generated code looks like.
In order to make Aron generate a C++ class for you, you first have to tell the program how the object should look like. Second you need to add the file to cmake in order to create the code generation target.
Then start defining your data in ARON. A hello world example could look like this:
If you want to use a definition of another Aron file, you can include the file using the AronIncludes section. Simply add the files you want to include using a include tag:
After that, you can use the type definitions in your current xml file (you must specify the full namespace):
<?xml version="1.0" encoding="UTF-8" ?>
<AronTypeDefinition>
<CodeIncludes>
<Include include="<Eigen/Core>" />
<Include include="<Eigen/Geometry>" />
<Include include="<pcl/point_cloud.h>" />
<Include include="<pcl/point_types.h>" />
<Include include="<opencv2/core/core.hpp>" />
</CodeIncludes>
<GenerateTypes>
<IntEnum name="TheIntEnum">
<EnumValue key="INT_ENUM_VALUE_0" value="0" />
<EnumValue key="INT_ENUM_VALUE_1" value="1" />
<EnumValue key="INT_ENUM_VALUE_2" value="2" />
<EnumValue key="INT_ENUM_VALUE_3" value="3" />
<EnumValue key="INT_ENUM_VALUE_4" value="4" />
<EnumValue key="INT_ENUM_VALUE_5" value="5" />
<EnumValue key="INT_ENUM_VALUE_6" value="6" />
<EnumValue key="INT_ENUM_VALUE_7" value="7" />
<EnumValue key="INT_ENUM_VALUE_8" value="8" />
</IntEnum>
<Object name="armarx::mydata::arondto::MyData">
<objectchild key="the_int_enum">
<TheIntEnum />
</objectchild>
<ObjectChild key="the_dict">
<Dict>
<Float />
</Dict>
</ObjectChild>
<ObjectChild key='the_list'>
<List>
<Float />
</List>
</ObjectChild>
<ObjectChild key='the_short_matrix'>
<Matrix rows="5" cols="7" type="int16" />
</ObjectChild>
<ObjectChild key='the_double_quaternion'>
<Quaternion type="float64" />
</ObjectChild>
<ObjectChild key='the_position'>
<Position />
</ObjectChild>
<ObjectChild key='the_orientation'>
<Orientation />
</ObjectChild>
<ObjectChild key='the_pose'>
<Pose />
</ObjectChild>
<ObjectChild key='the_rgb24_image'>
<Image type="rgb24" />
</ObjectChild>
<ObjectChild key='the_xyzrgb_pointcloud'>
<PointCloud type="PointXYZRGB" />
</ObjectChild>
</Object>
</GenerateTypes>
</AronTypeDefinition>
#pragma once
#include <memory>
#include <string>
#include <vector>
#include <map>
#include <RobotAPI/interface/aron.h>
#include <RobotAPI/libraries/aron/core/codegenerator/codewriter/cpp/AronCppClass.h>
{
class NaturalIKControlMode
: public armarx::aron::codegenerator::cpp::AronCppClass
{
public:
enum class ImplEnum
{
CONTROL_MODE_0,
CONTROL_MODE_1,
CONTROL_MODE_2,
};
public:
using This = armarx::NaturalIKControlMode;
static constexpr ImplEnum CONTROL_MODE_0 = ImplEnum::CONTROL_MODE_0;
static constexpr ImplEnum CONTROL_MODE_1 = ImplEnum::CONTROL_MODE_1;
static constexpr ImplEnum CONTROL_MODE_2 = ImplEnum::CONTROL_MODE_2;
const std::map<ImplEnum, std::string> EnumToStringMap = {
{ImplEnum::CONTROL_MODE_0, "CONTROL_MODE_0"},
{ImplEnum::CONTROL_MODE_1, "CONTROL_MODE_1"},
{ImplEnum::CONTROL_MODE_2, "CONTROL_MODE_2"},
};
const std::map<std::string, ImplEnum> StringToEnumMap = {
{"CONTROL_MODE_0", ImplEnum::CONTROL_MODE_0},
{"CONTROL_MODE_1", ImplEnum::CONTROL_MODE_1},
{"CONTROL_MODE_2", ImplEnum::CONTROL_MODE_2},
};
const std::map<ImplEnum, int> EnumToValueMap = {
{ImplEnum::CONTROL_MODE_0, 0},
{ImplEnum::CONTROL_MODE_1, 1},
{ImplEnum::CONTROL_MODE_2, 2},
};
const std::map<int, ImplEnum> ValueToEnumMap = {
{0, ImplEnum::CONTROL_MODE_0},
{1, ImplEnum::CONTROL_MODE_1},
{2, ImplEnum::CONTROL_MODE_2},
};
public:
NaturalIKControlMode()
{
resetHard();
}
NaturalIKControlMode(const armarx::NaturalIKControlMode& i)
{
}
NaturalIKControlMode(const ImplEnum e)
{
}
public:
bool operator==(
const armarx::NaturalIKControlMode& i)
const
{
if (not (value == i.value))
{
return false;
}
return true;
}
virtual void resetHard() override
{
}
virtual void resetSoft() override
{
}
template<class T>
static T writeType(armarx::aron::type::WriterInterface<T>& aron_w, armarx::aron::type::Maybe aron_maybeType = armarx::aron::type::Maybe::eNone,
const armarx::aron::Path& aron_p = armarx::aron::Path())
{
std::map<std::string, int> aron_str2ValueMap;
return aron_w.
writeIntEnum(
"armarx::NaturalIKControlMode", aron_str2ValueMap, aron_maybeType, aron_p);
}
template<class T>
T write(armarx::aron::data::WriterInterface<T>& aron_w,
const armarx::aron::Path& aron_p = armarx::aron::Path())
const
{
}
template<class T>
void read(armarx::aron::data::ReaderInterface<T>& aron_r,
T& input)
{
using TNonConst = typename std::remove_const<T>::type;
{
const TNonConst* _suppressUnusedWarning;
(void) _suppressUnusedWarning;
}
this->resetSoft();
{
throw armarx::aron::error::AronException(__PRETTY_FUNCTION__, "The input to the read method must not be null.");
}
int aron_tmpValue;
value = ValueToEnumMap.at(aron_tmpValue);
}
{
return EnumToStringMap.at(value);
}
void fromString(
const std::string&
str)
{
if (
auto it = StringToEnumMap.find(
str); it == StringToEnumMap.end())
{
throw armarx::LocalException(
"The input name is not valid. Could net set the enum to value '" +
str +
"'");
}
else
{
}
}
operator int() const
{
return EnumToValueMap.at(value);
}
armarx::NaturalIKControlMode& operator=(ImplEnum v)
{
return *this;
}
armarx::NaturalIKControlMode& operator=(
const armarx::NaturalIKControlMode&
c)
{
return *this;
}
armarx::NaturalIKControlMode& operator=(int v)
{
if (auto it = ValueToEnumMap.find(v); it == ValueToEnumMap.end())
{
throw armarx::LocalException("The input int is not valid. Could net set the enum to value '" + std::to_string(v) + "'");
}
else
{
}
return *this;
}
};
}
{
class NaturalIKResult
: public armarx::aron::codegenerator::cpp::AronCppClass
{
public:
using This = armarx::NaturalIKResult;
armarx::NaturalIKControlMode control_mode;
std::vector<float> jointValues;
bool reached;
public:
NaturalIKResult()
{
resetHard();
}
public:
bool operator==(
const armarx::NaturalIKResult& i)
const
{
if (not (control_mode == i.control_mode))
{
return false;
}
if (not (jointValues == i.jointValues))
{
return false;
}
if (not (reached == i.reached))
{
return false;
}
return true;
}
virtual void resetHard() override
{
control_mode.resetHard();
jointValues = std::vector<float>();
reached = bool();
}
virtual void resetSoft() override
{
control_mode.resetSoft();
jointValues.clear();
reached = bool();
}
template<class T>
static T writeType(armarx::aron::type::WriterInterface<T>& aron_w, armarx::aron::type::Maybe aron_maybeType = armarx::aron::type::Maybe::eNone,
const armarx::aron::Path& aron_p = armarx::aron::Path())
{
std::map<std::string, T> aron_objectMembers;
auto aron_objectExtends = std::nullopt;
auto aron_variant_control_mode = armarx::NaturalIKControlMode::writeType(aron_w, armarx::aron::type::Maybe::eNone, armarx::aron::Path(aron_p, {"control_mode"}));
aron_objectMembers.emplace("control_mode", aron_variant_control_mode);
auto aron_variant_jointValues_dot_accepted_type = aron_w.
writeFloat(armarx::aron::type::Maybe::eNone, armarx::aron::Path(aron_p, {
"jointValues",
"::accepted_type"}));
auto aron_variant_jointValues = aron_w.
writeList(aron_variant_jointValues_dot_accepted_type, armarx::aron::type::Maybe::eNone, armarx::aron::Path(aron_p, {
"jointValues"}));
aron_objectMembers.emplace("jointValues", aron_variant_jointValues);
auto aron_variant_reached = aron_w.
writeBool(armarx::aron::type::Maybe::eNone, armarx::aron::Path(aron_p, {
"reached"}));
aron_objectMembers.emplace("reached", aron_variant_reached);
return aron_w.
writeObject(
"armarx::NaturalIKResult", aron_objectMembers, aron_objectExtends, aron_maybeType, aron_p);
}
template<class T>
T write(armarx::aron::data::WriterInterface<T>& aron_w,
const armarx::aron::Path& aron_p = armarx::aron::Path())
const
{
std::map<std::string, T> aron_objectMembers;
std::optional<T> aron_objectExtends;
auto aron_variant_control_mode = aron_w.
writeNull();
aron_variant_control_mode = control_mode.write(aron_w, armarx::aron::Path(aron_p, {"control_mode"}));
aron_objectMembers.emplace("control_mode", aron_variant_control_mode);
auto aron_variant_jointValues = aron_w.
writeNull();
std::vector<T> aron_variant_jointValues_listElements;
for(unsigned int aron_jointValues_it = 0; aron_jointValues_it < jointValues.size(); ++aron_jointValues_it)
{
auto aron_variant_jointValues_dot_at_lbrR_aron_jointValues_it_rbrR_ = aron_w.
writeNull();
aron_variant_jointValues_dot_at_lbrR_aron_jointValues_it_rbrR_ = aron_w.
writePrimitive(jointValues.at(aron_jointValues_it), armarx::aron::Path(aron_p, {
"jointValues", std::to_string(aron_jointValues_it)}));
aron_variant_jointValues_listElements.push_back(aron_variant_jointValues_dot_at_lbrR_aron_jointValues_it_rbrR_);
}
aron_variant_jointValues = aron_w.
writeList(aron_variant_jointValues_listElements, armarx::aron::Path(aron_p, {
"jointValues"}));
aron_objectMembers.emplace("jointValues", aron_variant_jointValues);
auto aron_variant_reached = aron_w.
writeNull();
aron_variant_reached = aron_w.
writePrimitive(reached, armarx::aron::Path(aron_p, {
"reached"}));
aron_objectMembers.emplace("reached", aron_variant_reached);
return aron_w.
writeDict(aron_objectMembers, aron_objectExtends, aron_p);
}
template<class T>
void read(armarx::aron::data::ReaderInterface<T>& aron_r,
T& input)
{
using TNonConst = typename std::remove_const<T>::type;
{
const TNonConst* _suppressUnusedWarning;
(void) _suppressUnusedWarning;
}
this->resetSoft();
{
throw armarx::aron::error::AronException(__PRETTY_FUNCTION__, "The input to the read method must not be null.");
}
std::map<std::string, TNonConst> aron_objectMembers;
aron_r.
readDict(input, aron_objectMembers);
control_mode.read<
T>(aron_r, aron_objectMembers.at(
"control_mode"));
std::vector<TNonConst> aron_jointValues_listElements;
aron_r.readList(aron_objectMembers.at("jointValues"), aron_jointValues_listElements);
for (const auto& aron_jointValues_listValue : aron_jointValues_listElements)
{
float aron_jointValues_listTmp;
aron_r.readPrimitive(aron_jointValues_listValue, aron_jointValues_listTmp);
jointValues.push_back(aron_jointValues_listTmp);
}
aron_r.readPrimitive(aron_objectMembers.at("reached"), reached);
}
{
armarx::aron::data::writer::VariantWriter writer;
}
{
This t;
t.fromAron(input);
return t;
}
{
armarx::aron::data::reader::VariantReader reader;
this->read<armarx::aron::data::reader::VariantReader::InputType>(reader, (input));
}
{
armarx::aron::type::writer::VariantWriter writer;
}
};
}
void readPrimitive(InputType &input, int &i, Path &p)
virtual void readDict(InputType &input, std::map< std::string, InputTypeNonConst > &elements, Path &)=0
virtual bool readNull(InputType &input)
virtual ReturnType writeList(const std::vector< ReturnType > &elements, const Path &p)=0
ReturnType writePrimitive(const int i, const Path &p=Path())
virtual ReturnType writeDict(const std::map< std::string, ReturnType > &elements, const std::optional< ReturnType > &extends, const Path &p)=0
virtual ReturnType writeNull()
static PointerType DynamicCastAndCheck(const VariantPtr &n)
virtual ReturnType writeList(const ReturnType &acceptedType, const type::Maybe maybe, const Path &p)=0
Construct a list from the params.
virtual ReturnType writeObject(const std::string &name, const std::vector< std::string > &templates, const std::vector< std::string > &templateInstantiations, const std::map< std::string, ReturnType > &memberTypes, const std::optional< ReturnType > &extends, const type::Maybe maybe, const Path &p)=0
Construct an object from the params.
virtual ReturnType writeIntEnum(const std::string &name, const std::map< std::string, int > &acceptedValues, const std::string &defaultValue, const type::Maybe maybe, const Path &p)=0
Construct a int enum from the params.
virtual ReturnType writeFloat(const std::optional< float > &defaultValue, const type::Maybe maybe, const Path &p)=0
Construct a float from the params.
virtual ReturnType writeBool(const std::optional< bool > &defaultValue, const type::Maybe maybe, const Path &p)=0
Construct a bool from the params.
static std::shared_ptr< Object > DynamicCastAndCheck(const VariantPtr &n)
bool operator==(const ReplicaObserver &lhs, const ReplicaObserver &rhs)
std::shared_ptr< Dict > DictPtr
std::shared_ptr< Object > ObjectPtr
void write(WriterT &aron_w, const Eigen::Matrix< EigenT, rows, cols, options > &input, typename WriterT::ReturnType &ret, const armarx::aron::Path &aron_p=armarx::aron::Path())
double v(double t, double v0, double a0, double j)
const char * toString(InteractionFeedbackType type)
This file offers overloads of toIce() and fromIce() functions for STL container types.
void read(auto &eigen, auto *table)
void toAron(arondto::PackagePath &dto, const PackageFileLocation &bo)
void fromAron(const arondto::PackagePath &dto, PackageFileLocation &bo)
std::shared_ptr< Value > value()
Further, the code generation creates methods to compare two classes with each other (right now only operator==).
This means, when using Aron, you don't need to mess around with the Aron DTOs and Aron objects, you only have to set and use plain C++ members of a generated class!