diff --git a/CMakeLists.txt b/CMakeLists.txt index b8db2ba..e025db8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,3 +8,5 @@ find_package(Rock) rock_init() rock_standard_layout() + +install(DIRECTORY configuration/schema/ DESTINATION share/envire_types/schema) diff --git a/configuration/schema/Inertial_schema.yml b/configuration/schema/Inertial_schema.yml new file mode 100644 index 0000000..dc50058 --- /dev/null +++ b/configuration/schema/Inertial_schema.yml @@ -0,0 +1,24 @@ +name: + type: string + required: true +mass: + type: number + required: true +xx: + type: number + required: true +xy: + type: number + required: true +xz: + type: number + required: true +yy: + type: number + required: true +yz: + type: number + required: true +zz: + type: number + required: true diff --git a/configuration/schema/Link_schema.yml b/configuration/schema/Link_schema.yml new file mode 100644 index 0000000..4352f07 --- /dev/null +++ b/configuration/schema/Link_schema.yml @@ -0,0 +1,3 @@ +name: + type: string + required: true diff --git a/configuration/schema/World_schema.yml b/configuration/schema/World_schema.yml new file mode 100644 index 0000000..5d39bcd --- /dev/null +++ b/configuration/schema/World_schema.yml @@ -0,0 +1,6 @@ +name: + type: string + required: true +prefix: + type: string + required: true diff --git a/configuration/schema/geometry/Box_schema.yml b/configuration/schema/geometry/Box_schema.yml new file mode 100644 index 0000000..b8ae6ce --- /dev/null +++ b/configuration/schema/geometry/Box_schema.yml @@ -0,0 +1,82 @@ +name: + type: string + required: true +size: + type: object + required: true + properties: + x: + type: number + required: true + y: + type: number + required: true + z: + type: number + required: true +material: + type: object + properties: + name: + type: string + ambientColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + diffuseColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + specularColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + shininess: + type: number + textureFilename: + type: string diff --git a/configuration/schema/geometry/Capsule_schema.yml b/configuration/schema/geometry/Capsule_schema.yml new file mode 100644 index 0000000..142c7ab --- /dev/null +++ b/configuration/schema/geometry/Capsule_schema.yml @@ -0,0 +1,75 @@ +name: + type: string + required: true +radius: + type: number + required: true +length: + type: number + required: true +material: + type: object + properties: + name: + type: string + ambientColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + diffuseColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + specularColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + shininess: + type: number + textureFilename: + type: string diff --git a/configuration/schema/geometry/Cylinder_schema.yml b/configuration/schema/geometry/Cylinder_schema.yml new file mode 100644 index 0000000..142c7ab --- /dev/null +++ b/configuration/schema/geometry/Cylinder_schema.yml @@ -0,0 +1,75 @@ +name: + type: string + required: true +radius: + type: number + required: true +length: + type: number + required: true +material: + type: object + properties: + name: + type: string + ambientColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + diffuseColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + specularColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + shininess: + type: number + textureFilename: + type: string diff --git a/configuration/schema/geometry/Heightfield_schema.yml b/configuration/schema/geometry/Heightfield_schema.yml new file mode 100644 index 0000000..6f6be19 --- /dev/null +++ b/configuration/schema/geometry/Heightfield_schema.yml @@ -0,0 +1,69 @@ +name: + type: string + required: true +material: + type: object + properties: + name: + type: string + ambientColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + diffuseColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + specularColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + shininess: + type: number + textureFilename: + type: string diff --git a/configuration/schema/geometry/Material_schema.yml b/configuration/schema/geometry/Material_schema.yml new file mode 100644 index 0000000..31b952e --- /dev/null +++ b/configuration/schema/geometry/Material_schema.yml @@ -0,0 +1,63 @@ +name: + type: string +ambientColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 +diffuseColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 +specularColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 +shininess: + type: number +textureFilename: + type: string diff --git a/configuration/schema/geometry/Mesh_schema.yml b/configuration/schema/geometry/Mesh_schema.yml new file mode 100644 index 0000000..0cec041 --- /dev/null +++ b/configuration/schema/geometry/Mesh_schema.yml @@ -0,0 +1,85 @@ +name: + type: string + required: true +filename: + type: string + required: true +scale: + type: object + required: true + properties: + x: + type: number + required: true + y: + type: number + required: true + z: + type: number + required: true +material: + type: object + properties: + name: + type: string + ambientColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + diffuseColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + specularColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + shininess: + type: number + textureFilename: + type: string diff --git a/configuration/schema/geometry/Plane_schema.yml b/configuration/schema/geometry/Plane_schema.yml new file mode 100644 index 0000000..48da2d5 --- /dev/null +++ b/configuration/schema/geometry/Plane_schema.yml @@ -0,0 +1,79 @@ +name: + type: string + required: true +size: + type: object + required: true + properties: + x: + type: number + required: true + y: + type: number + required: true +material: + type: object + properties: + name: + type: string + ambientColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + diffuseColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + specularColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + shininess: + type: number + textureFilename: + type: string diff --git a/configuration/schema/geometry/Sphere_schema.yml b/configuration/schema/geometry/Sphere_schema.yml new file mode 100644 index 0000000..d5dff01 --- /dev/null +++ b/configuration/schema/geometry/Sphere_schema.yml @@ -0,0 +1,72 @@ +name: + type: string + required: true +radius: + type: number + required: true +material: + type: object + properties: + name: + type: string + ambientColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + diffuseColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + specularColor: + type: object + properties: + r: + type: number + minimum: 0.0 + maximum: 1.0 + g: + type: number + minimum: 0.0 + maximum: 1.0 + b: + type: number + minimum: 0.0 + maximum: 1.0 + a: + type: number + minimum: 0.0 + maximum: 1.0 + shininess: + type: number + textureFilename: + type: string diff --git a/configuration/schema/joints/Continuous_schema.yml b/configuration/schema/joints/Continuous_schema.yml new file mode 100644 index 0000000..0bafa63 --- /dev/null +++ b/configuration/schema/joints/Continuous_schema.yml @@ -0,0 +1,22 @@ +name: + type: string + required: true +axis: + type: object + required: true + properties: + x: + type: number + required: true + y: + type: number + required: true + z: + type: number + required: true +maxEffort: + type: number + required: true +maxVelocity: + type: number + required: true diff --git a/configuration/schema/joints/Fixed_schema.yml b/configuration/schema/joints/Fixed_schema.yml new file mode 100644 index 0000000..4352f07 --- /dev/null +++ b/configuration/schema/joints/Fixed_schema.yml @@ -0,0 +1,3 @@ +name: + type: string + required: true diff --git a/configuration/schema/joints/Prismatic_schema.yml b/configuration/schema/joints/Prismatic_schema.yml new file mode 100644 index 0000000..0bafa63 --- /dev/null +++ b/configuration/schema/joints/Prismatic_schema.yml @@ -0,0 +1,22 @@ +name: + type: string + required: true +axis: + type: object + required: true + properties: + x: + type: number + required: true + y: + type: number + required: true + z: + type: number + required: true +maxEffort: + type: number + required: true +maxVelocity: + type: number + required: true diff --git a/configuration/schema/joints/Revolute_schema.yml b/configuration/schema/joints/Revolute_schema.yml new file mode 100644 index 0000000..1020c9f --- /dev/null +++ b/configuration/schema/joints/Revolute_schema.yml @@ -0,0 +1,28 @@ +name: + type: string + required: true +axis: + type: object + required: true + properties: + x: + type: number + required: true + y: + type: number + required: true + z: + type: number + required: true +minPosition: + type: number + required: true +maxPosition: + type: number + required: true +maxEffort: + type: number + required: true +maxVelocity: + type: number + required: true diff --git a/configuration/schema/motors/DC_schema.yml b/configuration/schema/motors/DC_schema.yml new file mode 100644 index 0000000..40652a5 --- /dev/null +++ b/configuration/schema/motors/DC_schema.yml @@ -0,0 +1,15 @@ +name: + type: string + required: true +minValue: + type: number + required: true +maxValue: + type: number + required: true +maxEffort: + type: number + required: true +maxSpeed: + type: number + required: true diff --git a/configuration/schema/motors/DirectEffort_schema.yml b/configuration/schema/motors/DirectEffort_schema.yml new file mode 100644 index 0000000..7673a7f --- /dev/null +++ b/configuration/schema/motors/DirectEffort_schema.yml @@ -0,0 +1,17 @@ +name: + type: string + required: true +minValue: + type: number + required: true +maxValue: + type: number + required: true +maxEffort: + type: number + required: true +maxSpeed: + type: number + required: true +maxEffortControl: + type: number diff --git a/configuration/schema/motors/FeedForwardEffort_schema.yml b/configuration/schema/motors/FeedForwardEffort_schema.yml new file mode 100644 index 0000000..7673a7f --- /dev/null +++ b/configuration/schema/motors/FeedForwardEffort_schema.yml @@ -0,0 +1,17 @@ +name: + type: string + required: true +minValue: + type: number + required: true +maxValue: + type: number + required: true +maxEffort: + type: number + required: true +maxSpeed: + type: number + required: true +maxEffortControl: + type: number diff --git a/configuration/schema/motors/PID_schema.yml b/configuration/schema/motors/PID_schema.yml new file mode 100644 index 0000000..c6e3007 --- /dev/null +++ b/configuration/schema/motors/PID_schema.yml @@ -0,0 +1,24 @@ +name: + type: string + required: true +minValue: + type: number + required: true +maxValue: + type: number + required: true +maxEffort: + type: number + required: true +maxSpeed: + type: number + required: true +p: + type: number + required: true +i: + type: number + required: true +d: + type: number + required: true diff --git a/configuration/schema/sensors/CameraSensor_schema.yml b/configuration/schema/sensors/CameraSensor_schema.yml new file mode 100644 index 0000000..dcf7c60 --- /dev/null +++ b/configuration/schema/sensors/CameraSensor_schema.yml @@ -0,0 +1,9 @@ +name: + type: string + required: true +opening_width: + type: number + required: true +opening_height: + type: number + required: true diff --git a/configuration/schema/sensors/Joint6DOFSensor_schema.yml b/configuration/schema/sensors/Joint6DOFSensor_schema.yml new file mode 100644 index 0000000..d24e1c7 --- /dev/null +++ b/configuration/schema/sensors/Joint6DOFSensor_schema.yml @@ -0,0 +1,9 @@ +name: + type: string + required: true +link: + type: string + required: true +joint: + type: string + required: true diff --git a/configuration/schema/sensors/RaySensor_schema.yml b/configuration/schema/sensors/RaySensor_schema.yml new file mode 100644 index 0000000..6977639 --- /dev/null +++ b/configuration/schema/sensors/RaySensor_schema.yml @@ -0,0 +1,9 @@ +name: + type: string + required: true +max_distance: + type: number + required: true +opening_width: + type: number + required: true diff --git a/configuration/schema/sensors/RotatingRaySensor_schema.yml b/configuration/schema/sensors/RotatingRaySensor_schema.yml new file mode 100644 index 0000000..4352f07 --- /dev/null +++ b/configuration/schema/sensors/RotatingRaySensor_schema.yml @@ -0,0 +1,3 @@ +name: + type: string + required: true diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 167083d..8d48723 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -51,3 +51,4 @@ rock_library(envire_types ) install_plugin_info(envire_types) +add_compile_definitions(SCHEMA_PATH=\"${CMAKE_INSTALL_PREFIX}/share/envire_types/schema\") diff --git a/src/World.hpp b/src/World.hpp index cd2afce..ec1b17e 100644 --- a/src/World.hpp +++ b/src/World.hpp @@ -4,6 +4,7 @@ #include #include +#include #include namespace envire diff --git a/src/registration/TypeCreatorFactory.cpp b/src/registration/TypeCreatorFactory.cpp index 23ceda0..737d950 100644 --- a/src/registration/TypeCreatorFactory.cpp +++ b/src/registration/TypeCreatorFactory.cpp @@ -1,6 +1,11 @@ - #include "TypeCreatorFactory.hpp" +#include +#include +#include +#include + + namespace envire { namespace types @@ -9,6 +14,22 @@ namespace envire void TypeCreatorFactory::registerTypeCreator(std::string className, CreatorPtr &creator) { getCreatorMap()[className] = creator; + + registerConfigSchema(className); + } + + void TypeCreatorFactory::registerConfigSchema(const std::string& className) + { + auto configSchemaPath = setupConfigSchemaPath(className); + try + { + auto configSchema = configmaps::ConfigSchema{configmaps::ConfigMap::fromYamlFile(configSchemaPath)}; + getConfigSchemaMap()[className] = configSchema; + } + catch (std::runtime_error e) + { + LOG_ERROR_S << "Could not load config schema for type " << className << ": " << e.what(); + } } envire::core::ItemBase::Ptr TypeCreatorFactory::createItem(std::string className, configmaps::ConfigMap &configmap) @@ -19,6 +40,18 @@ namespace envire return NULL; } + configmaps::ConfigSchema configSchema; + if (!getConfigSchema(className, configSchema)) + { + LOG_WARN_S << "No config schema registered for the type " << className; + } + else if(!configSchema.validate(configmap)) + { + // TODO: Handle name not being a string + const auto nameString = configmap.hasKey("name") ? std::string{"; item name: "} + configmap["name"].toString() : std::string{""}; + LOG_ERROR_S << "Invalid configuration for type " << className << nameString; + } + return creator->createItem(configmap); } @@ -33,10 +66,50 @@ namespace envire return false; } + bool TypeCreatorFactory::getConfigSchema(const std::string& className, configmaps::ConfigSchema& configSchema) + { + auto configSchemaMap = getConfigSchemaMap(); + auto configSchemaItr = configSchemaMap.find(className); + if (configSchemaItr == std::end(configSchemaMap)) + { + return false; + } + + configSchema = configSchemaItr->second; + return true; + } + + std::string TypeCreatorFactory::setupConfigSchemaPath(const std::string& className) + { + auto split = [](const std::string& s, char delimiter = ':') + { + std::vector result; + auto ss = std::stringstream{s}; + std::string item; + while (std::getline(ss, item, delimiter)) + { + result.push_back(item); + } + return result; + }; + + const auto exploded = split(className); + const auto len = exploded.size(); + const auto basePath = std::string{SCHEMA_PATH}; + + return basePath + "/" + (len > 5 ? exploded[len-3] + "/" : "") + exploded[len-1] + "_schema.yml"; + } + TypeCreatorFactory::CreatorMap& TypeCreatorFactory::getCreatorMap() { static CreatorMap creators; return creators; } + + TypeCreatorFactory::ConfigSchemaMap& TypeCreatorFactory::getConfigSchemaMap() + { + static ConfigSchemaMap configSchemas; + return configSchemas; + } } } diff --git a/src/registration/TypeCreatorFactory.hpp b/src/registration/TypeCreatorFactory.hpp index 3e86292..52930a1 100644 --- a/src/registration/TypeCreatorFactory.hpp +++ b/src/registration/TypeCreatorFactory.hpp @@ -2,10 +2,11 @@ #pragma once #include -#include #include +#include #include +#include #include "TypeCreatorInterface.hpp" @@ -16,7 +17,8 @@ namespace envire class TypeCreatorFactory { typedef std::shared_ptr CreatorPtr; - typedef std::map CreatorMap; + typedef std::unordered_map CreatorMap; + typedef std::unordered_map ConfigSchemaMap; public: // TODO: if the className is already registered @@ -26,8 +28,13 @@ namespace envire static bool getCreator(std::string className, CreatorPtr& creator); + static bool getConfigSchema(const std::string& className, configmaps::ConfigSchema& configSchema); + private: + static void registerConfigSchema(const std::string& className); + static std::string setupConfigSchemaPath(const std::string& className); static CreatorMap& getCreatorMap(); + static ConfigSchemaMap& getConfigSchemaMap(); }; } }