/* * TI Voxel Lib component. * * Copyright (c) 2014 Texas Instruments Inc. */ #ifndef VOXEL_CONFIGURATION_H #define VOXEL_CONFIGURATION_H #include "Common.h" #include "Serializable.h" #include "DataPacket.h" #include "HardwareSerializer.h" #define FILE_PREFIX "file:" #define CALIB_DISABLE "calib_disable" namespace Voxel { /** * \ingroup Util */ struct SDKVersion { uint8_t major, minor, patch, abi, conf; }; class VOXEL_EXPORT Configuration { protected: struct _Path { String installPath; String environmentVariable; }; String _sdkPath; String _sdkVersion; Vector _pathKeys; Vector _pathValues; static const Map _pathTypes; bool _getPaths(const String &type, Vector &paths); bool _get(const String &type, String &name); static bool _addPath(const String &type, const String &path); public: static SDKVersion getSDKVersion(); Configuration(); inline bool getFirmwarePaths(Vector &paths) { return _getPaths("fw", paths); } inline bool getConfPaths(Vector &paths) { return _getPaths("conf", paths); } inline bool getLibPaths(Vector &paths) { return _getPaths("lib", paths); } inline static bool addFirmwarePath(const String &path) { return _addPath("fw", path); } inline static bool addConfPath(const String &path) { return _addPath("conf", path); } inline static bool addLibPath(const String &path) { return _addPath("lib", path); } static bool addPathToEnvironmentVariable(const String &environmentVariable, const String &path, bool prepend = true); inline static bool getEnvironmentVariable(const String &environmentVariable, String &value) { char *p = getenv(environmentVariable.c_str()); if(p) { value = p; return true; } return false; } static bool setEnvironmentVariable(const String &environmentVariable, const String &value); inline static bool setSDKPath(const String &path) { return setEnvironmentVariable("VOXEL_SDK_PATH", path); } inline static bool getSDKPath(String &path) { return getEnvironmentVariable("VOXEL_SDK_PATH", path); } bool getLocalPath(const String &type, String &path); inline bool getLocalFirmwarePath(String &path) { return getLocalPath("fw", path); } inline bool getLocalConfPath(String &path) { return getLocalPath("conf", path); } inline bool getLocalLibPath(String &path) { return getLocalPath("lib", path); } bool getLocalFile(const String &type, String &fileName); inline bool getLocalFirmwareFile(String &fileName) { return getLocalFile("fw", fileName); } inline bool getLocalConfFile(String &fileName) { return getLocalFile("conf", fileName); } inline bool getLocalLibFile(String &fileName) { return getLocalFile("lib", fileName); } /// Updates "name" to full path inline bool getConfFile(String &fileName) { return _get("conf", fileName); } inline bool getFirmwareFile(String &fileName) { return _get("fw", fileName); } inline bool geLibFile(String &fileName) { return _get("lib", fileName); } }; class ConfigurationFile; class VOXEL_EXPORT ConfigSet { protected: bool _get(const String &name, String &value) const; bool _set(const String &name, const String &value); public: Map params; Vector paramNames; bool remove(const String &name); bool isEmpty() { return params.size() == 0; } bool isPresent(const String &name) const; String get(const String &name) const; int getInteger(const String &name) const; float getFloat(const String &name) const; bool getBoolean(const String &name) const; bool set(const String &name, const String &value); bool setInteger(const String &name, int value); bool setFloat(const String &name, float value); bool setBoolean(const String &name, bool value); friend class ConfigurationFile; }; struct ConfigDataPacket: public DataPacket { enum PacketType { PACKET_CONFIG = 0, PACKET_2D_DATA_FILE = 1 }; ConfigDataPacket(): DataPacket() {} }; class MainConfigurationFile; class VOXEL_EXPORT ConfigurationFile { protected: bool _get(const String §ion, const String &name, String &value) const; bool _set(const String §ion, const String &name, const String &value); String _fileName; Map> _dataFiles; MainConfigurationFile *_mainConfigurationFile; int _id, _parentID; String _profileName; mutable Mutex _mutex; bool _serializeAllDataFiles(OutputStream &out); bool _saveAllDataFiles(const String &prefix); template bool _getData(const String &fileName, Vector &data); template bool _setData(const String &fileName, const Vector &data); bool _copyFromParentIfNotPresent(ConfigurationFile *other, bool recurse = true); public: typedef Map ConfigSetMap; enum Location { IN_HOST = 0, IN_CAMERA = 1 }; protected: Location _location; public: ConfigSetMap configs; inline Location getLocation() const { return _location; } inline int getID() const { return _id; } inline int getParentID() const { return _parentID; } inline const String &getProfileName() const { return _profileName; } virtual bool isPresent(const String §ion, const String &name, bool includeParent = true) const; virtual String get(const String §ion, const String &name) const; inline void setProfileName(const String &name) { _profileName = name; set("global", "name", name); } inline void setID(const int id) { _id = id; setInteger("global", "id", id); } inline void setParentID(const int id) { _parentID = id; setInteger("global", "parent", id); } template bool getFile(const String §ion, const String &name, String &fileName, Vector &data); int getInteger(const String §ion, const String &name) const; float getFloat(const String §ion, const String &name) const; bool getBoolean(const String §ion, const String &name) const; virtual bool set(const String §ion, const String &name, const String &value); template bool setFile(const String §ion, const String &name, const String &fileName, const Vector &data); bool setInteger(const String §ion, const String &name, int value); bool setFloat(const String §ion, const String &name, float value); bool setBoolean(const String §ion, const String &name, bool value); bool remove(const String §ion, const String &name); bool removeSection(const String §ion); virtual bool getConfigSet(const String §ion, const ConfigSet *&configSet, bool includeParent = true) const; virtual bool read(const String &configFile); virtual bool read(InputStream &in); virtual bool write(const String &configFile = ""); virtual bool write(OutputStream &out); bool isValidCameraProfile(); virtual bool removeFile(); inline void clear() { Lock _(_mutex); configs.clear(); } inline const String &getConfigFileName() { return _fileName; } ConfigurationFile(): ConfigurationFile(0) {} ConfigurationFile(MainConfigurationFile *mainConfigurationFile): _mainConfigurationFile(mainConfigurationFile), _id(-1), _parentID(-1), _location(IN_HOST) {} ConfigurationFile(const ConfigurationFile &other) { operator =(other); } inline ConfigurationFile &operator =(const ConfigurationFile &other) { configs = other.configs; _fileName = other._fileName; _mainConfigurationFile = other._mainConfigurationFile; _id = other._id; _profileName = other._profileName; _parentID = other._parentID; _location = other._location; _dataFiles = other._dataFiles; return *this; } inline bool mergeParentConfiguration() { return _copyFromParentIfNotPresent(this); } inline ConfigurationFile ©(const ConfigurationFile &other) { return operator =(other); } virtual ~ConfigurationFile() {} friend class MainConfigurationFile; }; template bool ConfigurationFile::getFile(const String §ion, const String &name, String &fileName, Vector &data) { String v = get(section, name); if(v.compare(0, sizeof(FILE_PREFIX) - 1, FILE_PREFIX) != 0 || v.size() <= sizeof(FILE_PREFIX) - 1) { logger(LOG_ERROR) << "ConfigurationFile: section = " << section << ", name = " << name << ", is not a file type." << std::endl; return false; } fileName = v.substr(sizeof(FILE_PREFIX) - 1); return _getData(fileName, data); } template bool ConfigurationFile::setFile(const String §ion, const String &name, const String &fileName, const Vector &data) { return _setData(fileName, data) && set(section, name, "file:" + fileName); } template bool ConfigurationFile::_setData(const String &fileName, const Vector &data) { Configuration c; String f = fileName; if(!c.getLocalConfFile(f)) { logger(LOG_ERROR) << "ConfigurationFile: Failed to locate file '" << fileName << "'" << std::endl; return false; } OutputFileStream fs(f, std::ios::out | std::ios::binary); if(!fs.good()) { logger(LOG_ERROR) << "ConfigurationFile: Could not open file '" << fileName << "'" << std::endl; return false; } fs.write((const char *)data.data(), data.size()*sizeof(T)); fs.close(); _dataFiles[fileName].resize(data.size()*sizeof(T)); memcpy(_dataFiles[fileName].data(), data.data(), data.size()*sizeof(T)); return true; } struct CalibrationInformation { String name; int id; Vector definingParameters; Vector calibrationParameters; }; class VOXEL_EXPORT MainConfigurationFile: public ConfigurationFile { protected: Map _cameraProfiles; Map _cameraProfileNames; int _defaultCameraProfileID, _defaultCameraProfileIDInHardware; int _currentCameraProfileID; ConfigurationFile *_currentCameraProfile; bool _updateCameraProfileList(); String _mainConfigName, _hardwareID; int _getNewCameraProfileID(bool inHost = true); bool _saveHardwareImage(Version &version, TimeStampType ×tamp, SerializedObject &so); HardwareSerializerPtr _hardwareSerializer; int _quantizationFactor; Map _calibrationInformation; bool _removeCameraProfile(const int id, bool updateHardware = true); bool _saveCameraProfileToHardware(int &id, Vector &newIDsAdded, Vector &oldIDsModified, bool saveParents = false, bool updateHardware = true, bool setAsDefault = false, const String &namePrefix = ""); bool _rollbackCameraProfiles(const Vector &newIDsAdded, const Vector &oldIDsModified); public: MainConfigurationFile(const String &name, const String &hardwareID, int quantizationFactor = 4, HardwareSerializerPtr hardwareSerializer = nullptr): _currentCameraProfile(nullptr), _defaultCameraProfileID(-1), _defaultCameraProfileIDInHardware(-1), _mainConfigName(name), _hardwareSerializer(hardwareSerializer), _quantizationFactor(quantizationFactor) { if(!hardwareSerializer) _hardwareSerializer = HardwareSerializerPtr(new HardwareSerializer()); } void setSerializationQuantizationFactor(int quantizationFactor) { _quantizationFactor = quantizationFactor; } virtual bool read(const String &configFile); bool readFromHardware(); bool writeToHardware(); inline bool hasHardwareConfigurationSupport() { return _hardwareSerializer && *_hardwareSerializer; } inline void setHardwareConfigSerializer(const HardwareSerializerPtr &hardwareSerializer) { _hardwareSerializer = hardwareSerializer; } virtual String get(const String §ion, const String &name) const; virtual bool isPresent(const String §ion, const String &name, bool includeParent = true) const; int addCameraProfile(const String &profileName, const int parentID = -1); bool setCurrentCameraProfile(const int id); bool removeAllHardwareCameraProfiles(); bool removeCameraProfile(const int id); bool saveCameraProfileToHardware(int &id, bool saveParents = false, bool setAsDefault = false, const String &namePrefix = ""); ConfigurationFile *getDefaultCameraProfile(); ConfigurationFile *getCameraProfile(const int id); template bool getFile(const String §ion, const String &name, String &fileName, Vector &data); inline int getDefaultCameraProfileID() { if(_defaultCameraProfileIDInHardware >= 0) return _defaultCameraProfileIDInHardware; else return _defaultCameraProfileID; } inline int getDefaultCameraProfileIDInHost() { return _defaultCameraProfileID; } inline int getDefaultCameraProfileIDInCamera() { return _defaultCameraProfileIDInHardware; } /// This only removes the default ID from hardware and not the profile itself bool removeDefaultCameraProfileIDInCamera(); bool setDefaultCameraProfile(const int id); inline void setHardwareID(const String &hwID) { _hardwareID = hwID; } inline int getCurrentProfileID() { return _currentCameraProfileID; } bool getCameraProfileName(const int id, String &cameraProfileName); inline const Map &getCameraProfileNames() { return _cameraProfileNames; } inline const Map &getCalibrationInformation() const { return _calibrationInformation; } virtual ~MainConfigurationFile() {} friend class ConfigurationFile; friend class DepthCamera; }; template bool ConfigurationFile::_getData(const String &fileName, Vector &data) { bool loadFromFile = false; if(_dataFiles.find(fileName) == _dataFiles.end()) { if(_mainConfigurationFile && _parentID >= 0) { ConfigurationFile *parentConfig = _mainConfigurationFile->getCameraProfile(_parentID); // TODO This does not handle circular references between profiles if(parentConfig && parentConfig->_getData(fileName, data)) return true; else loadFromFile = true; } else loadFromFile = true; } if(loadFromFile) { Configuration c; String f = fileName; if(!c.getConfFile(f)) { logger(LOG_ERROR) << "ConfigurationFile: Could not locate file '" << fileName << "'" << std::endl; return false; } InputFileStream fs(f, std::ios::in | std::ios::binary | std::ios::ate); if(!fs.good()) { logger(LOG_ERROR) << "ConfigurationFile: Could not open file '" << fileName << "'" << std::endl; return false; } int size = fs.tellg(); if(size == 0) { logger(LOG_ERROR) << "ConfigurationFile: Null config data '" << f << "'" << std::endl; return false; } Vector &d = _dataFiles[fileName]; d.resize(size); fs.seekg(std::ios::beg); fs.clear(); fs.read((char *)d.data(), size); } Vector &d = _dataFiles[fileName]; data.resize((d.size() + sizeof(T)/2)/sizeof(T)); memcpy(data.data(), d.data(), d.size()); return true; } template bool MainConfigurationFile::getFile(const String §ion, const String &name, String &fileName, Vector &data) { if(!_currentCameraProfile || !_currentCameraProfile->getFile(section, name, fileName, data)) return ConfigurationFile::getFile(section, name, fileName, data); else return true; } } #endif // CONFIGURATION_H