Skip to content
Snippets Groups Projects
Commit aa8d1b3e authored by Rainer Kartmann's avatar Rainer Kartmann
Browse files

Add segment core classes

parent a9ad5b12
No related branches found
No related tags found
1 merge request!89Implement core data structure of ArMem Memories
Showing
with 455 additions and 4 deletions
......@@ -5,15 +5,31 @@ armarx_set_target("Library: ${LIB_NAME}")
set(LIBS
ArmarXCoreInterfaces
ArmarXCore
ArmarXCoreInterfaces ArmarXCore
aron
)
set(LIB_FILES
./ArMemBase.cpp
ArMemBase.cpp
segments/CoreSegment.cpp
segments/Entity.cpp
segments/EntityData.cpp
segments/MemoryID.cpp
segments/Memory.cpp
segments/ProviderSegment.cpp
segments/Time.cpp
)
set(LIB_HEADERS
./ArMemBase.h
ArMemBase.h
segments/CoreSegment.h
segments/Entity.h
segments/EntityData.h
segments/MemoryID.h
segments/Memory.h
segments/ProviderSegment.h
segments/Time.h
)
armarx_add_library("${LIB_NAME}" "${LIB_FILES}" "${LIB_HEADERS}" "${LIBS}")
#include "CoreSegment.h"
#pragma once
#include <map>
#include <memory>
#include <string>
#include "ProviderSegment.h"
namespace armarx::armem
{
/**
* @brief Data of a core segment containing multiple provider segments.
*/
class CoreSegment
{
public:
CoreSegment();
std::string name;
std::map<std::string, ProviderSegment> providers;
};
using CoreSegmentPtr = std::unique_ptr<CoreSegment>;
}
#include "Entity.h"
#pragma once
#include <map>
#include <memory>
#include <string>
#include <RobotAPI/interface/aron.h>
#include "Time.h"
#include "MemoryID.h"
#include "EntityData.h"
namespace armarx::armem
{
/**
* @brief Data of an entity at one point in time.
*/
struct EntitySnapshot
{
Time id;
std::vector<EntityDataPtr> instances;
EntityData* getInstance(int index)
{
size_t si = size_t(index);
return (index >= 0 && si < instances.size()) ? instances[si].get() : nullptr;
}
EntityData* getInstance(MemoryID id)
{
return id.hasInstanceIndex() ? getInstance(id.instanceIndex) : nullptr;
}
};
using EntitySnapshotPtr = std::unique_ptr<EntitySnapshot>;
/**
* @brief Data of an entity over a period of time.
*/
struct Entity
{
std::string name;
std::map<Time, EntitySnapshot> history;
};
using EntityPtr = std::unique_ptr<Entity>;
}
#include "EntityData.h"
#pragma once
#include <memory>
#include <RobotAPI/interface/aron.h>
#include "Time.h"
namespace armarx::armem
{
/**
* @brief Metadata of an entity value.
*/
struct Metadata
{
/// Time when this value was created.
Time timeCreated;
/// Time when this value was sent to the memory.
Time timeSent;
/// Time when this value has arrived at the memory.
Time timeArrived;
/// An optional importance, may be used for decay.
float importance = 1.0;
};
/**
* @brief Data of a single entity instance.
*/
struct EntityData
{
int index;
aron::AronDataPtr data;
Metadata metadata;
};
using EntityDataPtr = std::unique_ptr<EntityData>;
}
#include "Memory.h"
#pragma once
#include <map>
#include <memory>
#include <string>
#include "CoreSegment.h"
namespace armarx::armem
{
/**
* @brief Data of a memory consisting of multiple core segments.
*/
class Memory
{
public:
Memory();
std::string name;
std::map<std::string, CoreSegment> coreSegments;
};
using MemoryPtr = std::unique_ptr<Memory>;
}
#include "MemoryID.h"
#include <filesystem>
namespace armarx::armem
{
std::string MemoryID::str() const
{
std::filesystem::path p;
std::vector<std::string> items = getItems();
for (const auto& item : items)
{
p /= item;
}
return p;
}
MemoryID MemoryID::fromString(const std::string& string)
{
MemoryID id;
std::filesystem::path p = string;
auto it = p.begin();
if (it == p.end())
{
return id;
}
id.memoryName = *it;
if (++it == p.end())
{
return id;
}
id.coreSegmentName = *it;
if (++it == p.end())
{
return id;
}
id.providerSegmentName = *it;
if (++it == p.end())
{
return id;
}
id.entityName = *it;
if (++it == p.end())
{
return id;
}
id.timestamp = timestampFromStr(*it);
if (++it == p.end())
{
return id;
}
id.instanceIndex = instanceIndexFromStr(*it);
return id;
}
std::vector<std::string> MemoryID::getItems() const
{
std::vector<std::string> items;
items.push_back(memoryName);
if (!hasCoreSegmentName())
{
return items;
}
items.push_back(coreSegmentName);
if (!hasProviderSegmentName())
{
return items;
}
items.push_back(providerSegmentName);
if (!hasEntityName())
{
return items;
}
items.push_back(entityName);
if (!hasTimestamp())
{
return items;
}
items.push_back(timestampStr());
if (!hasInstanceIndex())
{
return items;
}
items.push_back(instanceIndexStr());
return items;
}
std::vector<std::string> MemoryID::getAllItems() const
{
return
{
memoryName, coreSegmentName, providerSegmentName, entityName,
timestampStr(), instanceIndexStr()
};
}
std::string MemoryID::timestampStr() const
{
return hasTimestamp() ? std::to_string(timestamp.toMicroSeconds()) : "";
}
std::string MemoryID::instanceIndexStr() const
{
return hasInstanceIndex() ? std::to_string(instanceIndex) : "";
}
IceUtil::Time MemoryID::timestampFromStr(const std::string& string)
{
return Time::microSeconds(parseInt(string, "timestamp"));
}
int MemoryID::instanceIndexFromStr(const std::string& string)
{
return parseInt(string, "instance index");
}
int MemoryID::parseInt(const std::string& string, const std::string& semanticName)
{
try
{
return std::stoi(string);
}
catch (const std::invalid_argument&) // if no conversion could be performed
{
// ToDo: handle by throwing an informative exception
(void) semanticName;
throw;
}
catch (const std::out_of_range&)
{
// if the converted value would fall out of the range of the result type
// or if the underlying function (std::strtol or std::strtoll) sets errno to ERANGE.
// ToDo: handle by throwing an informative exception
throw;
}
}
}
#pragma once
#include <string>
#include <vector>
#include "Time.h"
namespace armarx::armem
{
/**
* @brief A memory ID.
*
* Structure:
* `MemoryName/CoreSegmentName/ProviderSegmentName/EntityName/Timestamp/InstanceIndex`
*
* Example:
* `VisionMemory/RGBImages/PrimesenseRGB/image/1245321323/0`
*/
class MemoryID
{
public:
std::string memoryName = "";
std::string coreSegmentName = "";
std::string providerSegmentName = "";
std::string entityName = "";
Time timestamp = Time::microSeconds(-1);
int instanceIndex = -1;
std::string str() const;
static MemoryID fromString(const std::string& string);
std::vector<std::string> getItems() const;
std::vector<std::string> getAllItems() const;
bool hasMemoryName() const
{
return memoryName.size() > 0;
}
bool hasCoreSegmentName() const
{
return coreSegmentName.size() > 0;
}
bool hasProviderSegmentName() const
{
return providerSegmentName.size() > 0;
}
bool hasEntityName() const
{
return entityName.size() > 0;
}
bool hasTimestamp() const
{
return timestamp.toMicroSeconds() >= 0;
}
bool hasInstanceIndex() const
{
return instanceIndex >= 0;
}
std::string timestampStr() const;
std::string instanceIndexStr() const;
static Time timestampFromStr(const std::string& timestamp);
static int instanceIndexFromStr(const std::string& index);
private:
static int parseInt(const std::string& string, const std::string& semanticName);
};
}
#include "ProviderSegment.h"
#pragma once
#include <map>
#include <memory>
#include <string>
#include "Entity.h"
namespace armarx::armem
{
/**
* @brief Data of a provider segment containing multiple entities.
*/
class ProviderSegment
{
public:
using ID = std::string;
public:
ProviderSegment();
std::string name;
std::map<std::string, Entity> entities;
};
using ProviderSegmentPtr = std::unique_ptr<ProviderSegment>;
}
#include "Time.h"
#include <IceUtil/Time.h>
namespace armarx::armem
{
using Time = IceUtil::Time;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment