Skip to content
Snippets Groups Projects
Commit e039db0f authored by Christian Dreher's avatar Christian Dreher Committed by Rainer Kartmann
Browse files

Memory subscriptions

parent e8b9c4b5
No related branches found
No related tags found
No related merge requests found
Showing
with 328 additions and 137 deletions
......@@ -86,6 +86,14 @@
# ArmarX.ArMemExampleClient.tpc.pub.DebugObserver = DebugObserver
# ArmarX.ArMemExampleClient.tpc.sub.MemoryListener: Name of the `MemoryListener` topic to subscribe to.
# Attributes:
# - Default: MemoryUpdates
# - Case sensitivity: yes
# - Required: no
ArmarX.ArMemExampleClient.tpc.sub.MemoryListener = MemoryUpdates
# ArmarX.CachePath: Path for cache files. If relative path AND env. variable ARMARX_USER_CONFIG_DIR is set, the cache path will be made relative to ARMARX_USER_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${HOME}/.armarx)
# Attributes:
# - Default: mongo/.cache
......@@ -225,6 +233,6 @@
# - Case sensitivity: yes
# - Required: no
# - Possible values: {Debug, Error, Fatal, Important, Info, Undefined, Verbose, Warning}
# ArmarX.Verbosity = Info
ArmarX.Verbosity = Debug
......@@ -103,6 +103,14 @@
# ArmarX.ArMemExampleMemory.tpc.pub.DebugObserver = DebugObserver
# ArmarX.ArMemExampleMemory.tpc.pub.MemoryListener: Name of the `MemoryListener` topic to publish data to.
# Attributes:
# - Default: MemoryUpdates
# - Case sensitivity: yes
# - Required: no
ArmarX.ArMemExampleMemory.tpc.pub.MemoryListener = MemoryUpdates
# ArmarX.CachePath: Path for cache files. If relative path AND env. variable ARMARX_USER_CONFIG_DIR is set, the cache path will be made relative to ARMARX_USER_CONFIG_DIR. Otherwise if relative it will be relative to the default ArmarX config dir (${HOME}/.armarx)
# Attributes:
# - Default: mongo/.cache
......
......@@ -28,7 +28,6 @@
#include <RobotAPI/interface/aron.h>
#include <RobotAPI/libraries/armem/component/MemoryRemoteGui.h>
#include <RobotAPI/libraries/armem/client/MemoryWriter.h>
#include <RobotAPI/libraries/armem/memory/ice_conversions.h>
#include <RobotAPI/components/armem/ArMemExampleMemory/aron/Primitive.aron.generated.h>
......@@ -86,7 +85,6 @@ namespace armarx
}
ARMARX_CHECK_NOT_NULL(memory);
armem::MemoryID providerID;
if (true)
{
armem::data::AddSegmentInput input;
......@@ -111,11 +109,38 @@ namespace armarx
providerID = armem::MemoryID::fromString(result.segmentID);
}
armem::MemoryWriter writer(memory);
armem::MemoryID entityID = providerID;
entityID = providerID;
entityID.entityName = "example_entity";
// Subscribe to example_entity updates
memoryReader.subscribe(entityID, [&](const armem::MemoryID & sid, const std::vector<armem::MemoryID>& sids)
{
example_entityUpdated(sid);
});
task = new RunningTask<ArMemExampleClient>(this, &ArMemExampleClient::run);
task->start();
}
void ArMemExampleClient::onDisconnectComponent()
{
}
void ArMemExampleClient::onExitComponent()
{
}
void ArMemExampleClient::run()
{
sleep(2);
ARMARX_IMPORTANT << "Running now.";
armem::client::Writer writer(memory);
armem::MemoryID snapshotID;
{
armem::Commit commit;
......@@ -266,21 +291,17 @@ namespace armarx
{
primitives(writer);
}
}
void ArMemExampleClient::onDisconnectComponent()
{
}
void ArMemExampleClient::onExitComponent()
void ArMemExampleClient::example_entityUpdated(const armem::MemoryID& id)
{
ARMARX_IMPORTANT << "example_entity got updated";
// Fetch new data of example_entity and do something with it.
}
bool ArMemExampleClient::primitives(armem::MemoryWriter& writer)
bool ArMemExampleClient::primitives(armem::client::Writer& writer)
{
ARMARX_IMPORTANT << "Adding segment " << "Primitive" << "/" << getName();
......
......@@ -20,21 +20,21 @@
* GNU General Public License
*/
#pragma once
// ArmarX
#include <ArmarXCore/core/Component.h>
#include <ArmarXCore/interface/observers/ObserverInterface.h>
#include <ArmarXCore/util/tasks.h>
#include <ArmarXGui/libraries/ArmarXGuiComponentPlugins/LightweightRemoteGuiComponentPlugin.h>
// #include <RobotAPI/libraries/RobotAPIComponentPlugins/ArVizComponentPlugin.h>
// RobotAPI
//#include <RobotAPI/libraries/RobotAPIComponentPlugins/ArVizComponentPlugin.h>
#include <RobotAPI/interface/armem/MemoryInterface.h>
#include <RobotAPI/interface/armem/MemoryNameSystemInterface.h>
#include <RobotAPI/libraries/armem/client/MemoryClientComponentPlugin.h>
#include <RobotAPI/libraries/armem/client/ComponentPlugin.h>
#include <RobotAPI/libraries/armem/memory/Memory.h>
......@@ -52,7 +52,6 @@ namespace armarx
};
/**
* @defgroup Component-ArMemExampleClient ArMemExampleClient
* @ingroup RobotAPI-Components
......@@ -65,9 +64,9 @@ namespace armarx
* Detailed description of class ArMemExampleClient.
*/
class ArMemExampleClient :
virtual public armarx::Component
, virtual public armarx::armem::MemoryClientComponentPluginUser
, virtual public LightweightRemoteGuiComponentPluginUser
virtual public armarx::Component,
virtual public armarx::armem::client::ComponentPluginUser,
virtual public LightweightRemoteGuiComponentPluginUser
{
public:
......@@ -98,14 +97,25 @@ namespace armarx
/// @see PropertyUser::createPropertyDefinitions()
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override;
void run();
private:
armem::MemoryID providerID;
armem::MemoryID entityID;
// Callback for updates on `example_entity`.
void example_entityUpdated(const armem::MemoryID& id);
// Examples
bool primitives(armem::MemoryWriter& writer);
bool primitives(armem::client::Writer& writer);
private:
armarx::RunningTask<ArMemExampleClient>::pointer_type task;
armarx::DebugObserverInterfacePrx debugObserver;
std::string memoryName = "Example";
......
......@@ -142,7 +142,7 @@ namespace armarx
if (memoryName.size() > 0)
{
getProxy(memory, memoryName);
memoryReader = armem::MemoryReader(memory);
memoryReader = armem::client::Reader(memory);
}
// DebugObserver is optional (check for null on every call)
if (!debugObserverName.empty())
......
......@@ -33,7 +33,7 @@
#include <ArmarXCore/core/system/ImportExportComponent.h>
#include <RobotAPI/interface/armem/MemoryInterface.h>
#include <RobotAPI/libraries/armem/client/MemoryReader.h>
#include <RobotAPI/libraries/armem/client/Reader.h>
#include <RobotAPI/libraries/armem_gui/InstanceTreeWidget.h>
#include <RobotAPI/libraries/armem_gui/MemoryQueryWidget.h>
#include <RobotAPI/libraries/armem_gui/MemoryTreeWidget.h>
......@@ -126,7 +126,7 @@ namespace armarx
std::string memoryName;
armem::MemoryInterfacePrx memory;
armem::MemoryReader memoryReader;
armem::client::Reader memoryReader;
armem::MemoryPtr memoryData;
......
......@@ -106,6 +106,7 @@ set(SLICE_FILES
armem/ReadingInterface.ice
armem/WritingInterface.ice
armem/MemoryInterface.ice
armem/MemoryListenerInterface.ice
armem/MemoryNameSystemInterface.ice
armem/query.ice
......
......@@ -3,6 +3,7 @@
#include <RobotAPI/interface/armem/ReadingInterface.ice>
#include <RobotAPI/interface/armem/WritingInterface.ice>
#include <RobotAPI/interface/armem/MemoryInterface.ice>
#include <RobotAPI/interface/armem/MemoryListenerInterface.ice>
module armarx
......
#pragma once
#include <RobotAPI/interface/armem/memory.ice>
module armarx
{
module armem
{
interface MemoryListenerInterface
{
void memoryUpdated(data::MemoryIDs updatedIDs);
};
};
};
......@@ -21,6 +21,8 @@ module armarx
int instanceIndex = -1;
}
sequence<MemoryID> MemoryIDs;
module detail
{
class MemoryItem
......
......@@ -40,9 +40,11 @@ set(LIB_FILES
mns/MemoryNameSystemClientPlugin.cpp
mns/MemoryNameSystemComponentPlugin.cpp
client/MemoryWriter.cpp
client/MemoryReader.cpp
client/MemoryClientComponentPlugin.cpp
client/ComponentPlugin.cpp
client/Reader.cpp
client/ReaderComponentPlugin.cpp
client/Writer.cpp
client/WriterComponentPlugin.cpp
component/IceMemory.cpp
component/MemoryComponentPlugin.cpp
......@@ -83,9 +85,11 @@ set(LIB_HEADERS
mns/MemoryNameSystemClientPlugin.h
mns/MemoryNameSystemComponentPlugin.h
client/MemoryWriter.h
client/MemoryReader.h
client/MemoryClientComponentPlugin.h
client/ComponentPlugin.h
client/Reader.h
client/ReaderComponentPlugin.h
client/Writer.h
client/WriterComponentPlugin.h
component/IceMemory.h
component/MemoryComponentPlugin.h
......
#include <RobotAPI/libraries/armem/client/ComponentPlugin.h>
// ArmarX
#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
// RobotAPI
#include <RobotAPI/libraries/armem/error.h>
armarx::armem::client::ComponentPluginUser::ComponentPluginUser()
{
// pass
}
armarx::armem::client::ComponentPluginUser::~ComponentPluginUser()
{
// pass
}
#pragma once
// ArmarX
#include <ArmarXCore/core/Component.h>
// RobotAPI
#include <RobotAPI/interface/armem/MemoryInterface.h>
#include <RobotAPI/interface/armem/MemoryNameSystemInterface.h>
#include <RobotAPI/libraries/armem/client/ReaderComponentPlugin.h>
#include <RobotAPI/libraries/armem/client/WriterComponentPlugin.h>
#include <RobotAPI/libraries/armem/mns/MemoryNameSystemClientPlugin.h>
namespace armarx::armem::client
{
/**
* @brief Utility for connecting a Memory to Ice.
*/
class ComponentPluginUser :
virtual public ReaderComponentPluginUser,
virtual public WriterComponentPluginUser
{
public:
ComponentPluginUser();
~ComponentPluginUser() override;
};
}
#include "MemoryClientComponentPlugin.h"
#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
#include "../error.h"
namespace armarx::armem::plugins
{
MemoryClientComponentPlugin::~MemoryClientComponentPlugin()
{
}
}
namespace armarx::armem
{
MemoryClientComponentPluginUser::MemoryClientComponentPluginUser()
{
addPlugin(plugin);
}
}
#pragma once
#include <mutex>
#include <ArmarXCore/core/Component.h>
#include <RobotAPI/interface/armem/MemoryInterface.h>
#include <RobotAPI/interface/armem/MemoryNameSystemInterface.h>
#include "../mns/MemoryNameSystemClientPlugin.h"
#include "MemoryReader.h"
#include "MemoryWriter.h"
namespace armarx::armem::plugins
{
class MemoryClientComponentPlugin : public MemoryNameSystemClientPlugin
{
public:
using MemoryNameSystemClientPlugin::MemoryNameSystemClientPlugin;
virtual ~MemoryClientComponentPlugin() override;
};
}
namespace armarx::armem
{
/**
* @brief Utility for connecting a Memory to Ice.
*/
class MemoryClientComponentPluginUser :
virtual public ManagedIceObject
, virtual public plugins::MemoryNameSystemClientPluginUser
{
public:
MemoryClientComponentPluginUser();
private:
armem::plugins::MemoryClientComponentPlugin* plugin = nullptr;
};
}
#include "MemoryReader.h"
#include "Reader.h"
#include <ArmarXCore/core/logging/Logging.h>
#include "../memory/ice_conversions.h"
namespace armarx::armem
namespace armarx::armem::client
{
MemoryReader::MemoryReader(ReadingInterfacePrx memory) : memory(memory)
Reader::Reader(ReadingInterfacePrx memory) : memory(memory)
{
}
MemoryPtr MemoryReader::getLatestSnapshots()
MemoryPtr Reader::getLatestSnapshots()
{
armem::query::EntityQueryPtr entityQuery = new armem::query::entity::Single();
armem::query::ProviderSegmentQueryPtr providerQuery = new armem::query::provider::All({entityQuery});
......@@ -23,7 +23,7 @@ namespace armarx::armem
return queryToCpp(memoryQuery);
}
MemoryPtr MemoryReader::getAllData()
MemoryPtr Reader::getAllData()
{
armem::query::EntityQueryPtr entityQuery = new armem::query::entity::All();
armem::query::ProviderSegmentQueryPtr providerQuery = new armem::query::provider::All({entityQuery});
......@@ -33,12 +33,12 @@ namespace armarx::armem
return queryToCpp(memoryQuery);
}
data::MemoryPtr MemoryReader::query(query::MemoryQueryPtr query)
data::MemoryPtr Reader::query(query::MemoryQueryPtr query)
{
return this->query(query::MemoryQuerySeq{query});
}
data::MemoryPtr MemoryReader::query(query::MemoryQuerySeq queries)
data::MemoryPtr Reader::query(query::MemoryQuerySeq queries)
{
try
{
......@@ -59,14 +59,44 @@ namespace armarx::armem
return nullptr;
}
MemoryPtr MemoryReader::queryToCpp(query::MemoryQueryPtr query)
MemoryPtr Reader::queryToCpp(query::MemoryQueryPtr query)
{
return armem::fromIce<armem::MemoryPtr>(this->query(query));
}
MemoryPtr MemoryReader::queryToCpp(query::MemoryQuerySeq queries)
MemoryPtr Reader::queryToCpp(query::MemoryQuerySeq queries)
{
return armem::fromIce<armem::MemoryPtr>(this->query(queries));
}
void
Reader::updated(const std::vector<MemoryID>& updatedSnapshotIDs)
{
for (const auto& [subscription, callback] : callbacks)
{
std::vector<MemoryID> matchingSnapshotIDs;
for (const MemoryID& updatedSnapshotID : updatedSnapshotIDs)
{
if (contains(subscription, updatedSnapshotID))
{
matchingSnapshotIDs.push_back(updatedSnapshotID);
}
}
if (not matchingSnapshotIDs.empty())
{
callback(subscription, matchingSnapshotIDs);
}
}
}
void
Reader::subscribe(const MemoryID& id, callback callback)
{
callbacks[id] = callback;
}
}
#pragma once
#include <RobotAPI/interface/armem/ReadingInterface.h>
// STD/STL
#include <functional>
#include <unordered_map>
#include <vector>
// RobotAPI
#include <RobotAPI/interface/armem/ReadingInterface.h>
#include <RobotAPI/interface/armem/MemoryListenerInterface.h>
#include <RobotAPI/libraries/armem/core/ice_conversions.h>
#include <RobotAPI/libraries/armem/memory/Memory.h>
namespace armarx::armem
namespace armarx::armem::client
{
/**
* @brief Helps sending data to a memory.
*/
class MemoryReader
class Reader
{
using callback = std::function<void(const MemoryID& subscriptionID, const std::vector<MemoryID>& updatedSnapshotIDs)>;
public:
/**
* @brief Construct a memory reader.
* @param memory The memory proxy.
*/
MemoryReader(ReadingInterfacePrx memory = nullptr);
Reader(ReadingInterfacePrx memory = nullptr);
MemoryPtr getLatestSnapshots();
......@@ -32,17 +42,21 @@ namespace armarx::armem
MemoryPtr queryToCpp(query::MemoryQueryPtr query);
MemoryPtr queryToCpp(query::MemoryQuerySeq queries);
void updated(const std::vector<MemoryID>& updatedIDs);
void subscribe(const MemoryID& entityID, callback callback);
operator bool() const
{
return bool(memory);
}
public:
ReadingInterfacePrx memory;
private:
std::unordered_map<MemoryID, callback> callbacks;
};
......
#include <RobotAPI/libraries/armem/client/ReaderComponentPlugin.h>
// ArmarX
#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
// RobotAPI
#include <RobotAPI/libraries/armem/error.h>
armarx::armem::client::ReaderComponentPlugin::~ReaderComponentPlugin()
{
// pass
}
void
armarx::armem::client::ReaderComponentPlugin::postCreatePropertyDefinitions(PropertyDefinitionsPtr& properties)
{
MemoryNameSystemClientPlugin::postCreatePropertyDefinitions(properties);
properties->topic<MemoryListenerInterface>("MemoryUpdates");
}
armarx::armem::client::ReaderComponentPluginUser::ReaderComponentPluginUser()
{
addPlugin(plugin);
}
armarx::armem::client::ReaderComponentPluginUser::~ReaderComponentPluginUser()
{
// pass
}
void
armarx::armem::client::ReaderComponentPluginUser::memoryUpdated(const std::vector<data::MemoryID>& updatedIDsIce, const Ice::Current& current)
{
std::vector<MemoryID> updatedIDs;
fromIce(updatedIDsIce, updatedIDs);
memoryReader.updated(updatedIDs);
}
#pragma once
// STD/STL
#include <vector>
// ArmarX
#include <ArmarXCore/core/Component.h>
// RobotAPI
#include <RobotAPI/interface/armem/MemoryInterface.h>
#include <RobotAPI/interface/armem/MemoryListenerInterface.h>
#include <RobotAPI/interface/armem/MemoryNameSystemInterface.h>
#include <RobotAPI/libraries/armem/client/Reader.h>
#include <RobotAPI/libraries/armem/mns/MemoryNameSystemClientPlugin.h>
namespace armarx::armem::client
{
class ReaderComponentPlugin :
public plugins::MemoryNameSystemClientPlugin
{
public:
using plugins::MemoryNameSystemClientPlugin::MemoryNameSystemClientPlugin;
~ReaderComponentPlugin() override;
void postCreatePropertyDefinitions(PropertyDefinitionsPtr& properties) override;
};
class ReaderComponentPluginUser :
virtual public ManagedIceObject,
virtual public plugins::MemoryNameSystemClientPluginUser,
virtual public MemoryListenerInterface
{
public:
ReaderComponentPluginUser();
~ReaderComponentPluginUser() override;
void memoryUpdated(const std::vector<data::MemoryID>& updatedIDs, const Ice::Current& current) override;
protected:
Reader memoryReader;
private:
ReaderComponentPlugin* plugin = nullptr;
};
}
#include "MemoryWriter.h"
#include "Writer.h"
#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
#include "../error.h"
namespace armarx::armem
namespace armarx::armem::client
{
MemoryWriter::MemoryWriter(WritingInterfacePrx memory) : memory(memory)
Writer::Writer(WritingInterfacePrx memory) : memory(memory)
{
}
data::AddSegmentResult MemoryWriter::addSegment(const std::string& coreSegmentName, const std::string& providerSegmentName)
data::AddSegmentResult Writer::addSegment(const std::string& coreSegmentName, const std::string& providerSegmentName)
{
data::AddSegmentInput input;
input.coreSegmentName = coreSegmentName;
......@@ -20,14 +20,14 @@ namespace armarx::armem
return addSegment(input);
}
data::AddSegmentResult MemoryWriter::addSegment(const data::AddSegmentInput& input)
data::AddSegmentResult Writer::addSegment(const data::AddSegmentInput& input)
{
data::AddSegmentsResult results = addSegments({input});
ARMARX_CHECK_EQUAL(results.size(), 1);
return results.at(0);
}
data::AddSegmentsResult MemoryWriter::addSegments(const data::AddSegmentsInput& inputs)
data::AddSegmentsResult Writer::addSegments(const data::AddSegmentsInput& inputs)
{
ARMARX_CHECK_NOT_NULL(memory);
data::AddSegmentsResult results = memory->addSegments(inputs);
......@@ -36,7 +36,7 @@ namespace armarx::armem
}
CommitResult MemoryWriter::commit(Commit commit)
CommitResult Writer::commit(Commit commit)
{
ARMARX_CHECK_NOT_NULL(memory);
......@@ -74,7 +74,7 @@ namespace armarx::armem
}
EntityUpdateResult MemoryWriter::commit(const EntityUpdate& update)
EntityUpdateResult Writer::commit(const EntityUpdate& update)
{
armem::Commit commit;
commit.updates.push_back(update);
......
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