25#include <SimoxUtility/algorithm/contains.h>
26#include <SimoxUtility/algorithm/get_map_keys_values.h>
27#include <SimoxUtility/algorithm/string.h>
34#include <RobotAPI/interface/core/PoseBase.h>
54 commonVisu(descriptionSegment, proprioceptionSegment, localizationSegment)
61 robotUnit.plugin->setRobotUnitAsOptionalDependency(
true);
62 robotUnit.dataBuffer = std::make_unique<RobotUnit::Queue>();
73 const std::string robotUnitPrefix = RobotUnit::sensorValuePrefix;
76 defs->optional(robotUnit.waitForRobotUnit,
78 "Add the robot unit as dependency to the component. This memory requires a "
79 "running RobotUnit, therefore we should add it as explicit dependency.");
81 defs->optional(robotUnit.reader.properties.sensorPrefix,
82 robotUnitPrefix +
"SensorValuePrefix",
83 "Prefix of all sensor values.");
84 defs->optional(robotUnit.pollFrequency,
85 robotUnitPrefix +
"UpdateFrequency",
86 "The frequency to store values in Hz. All other values get discarded. "
87 "Minimum is 1, max is " +
88 std::to_string(RobotUnit::ROBOT_UNIT_MAXIMUM_FREQUENCY) +
".")
90 .setMax(RobotUnit::ROBOT_UNIT_MAXIMUM_FREQUENCY);
92 defs->optional(robotUnit.writer.properties.queueSizeWarningThreshold,
93 robotUnitPrefix +
"QueueSizeWarningThreshold",
94 "If the RobotStateWriter's data queue grows larger than this value, "
95 "a warning is logged (rate-limited).");
98 const std::string prefix =
"mem.";
102 descriptionSegment.defineProperties(defs, prefix +
"desc.");
103 exteroceptionSegment.defineProperties(defs, prefix +
"ext.");
104 proprioceptionSegment.defineProperties(defs, prefix +
"prop.");
105 localizationSegment.defineProperties(defs, prefix +
"loc.");
106 commonVisu.defineProperties(defs, prefix +
"visu.");
114 return "RobotStateMemory";
120 descriptionSegment.init();
121 proprioceptionSegment.init();
122 exteroceptionSegment.init();
123 localizationSegment.init();
126 robotUnit.pollFrequency =
127 std::clamp(robotUnit.pollFrequency, 0.F, RobotUnit::ROBOT_UNIT_MAXIMUM_FREQUENCY);
129 std::vector<std::string> includePaths;
133 for (
const std::string& projectName : packages)
135 if (projectName.empty())
141 const std::string pathsString = project.getIncludePaths();
142 std::vector<std::string> projectIncludePaths = simox::alg::split(pathsString,
";,");
144 includePaths.end(), projectIncludePaths.begin(), projectIncludePaths.end());
147 if (robotUnit.waitForRobotUnit)
149 usingProxy(robotUnit.plugin->getRobotUnitName());
157 ARMARX_CHECK(not robotUnit.reader.task or not robotUnit.reader.task->isRunning());
158 ARMARX_CHECK(not robotUnit.writer.task or not robotUnit.writer.task->isRunning());
159 robotUnit.dataBuffer = std::make_unique<RobotUnit::Queue>();
165 ARMARX_INFO <<
"Debug observer set for LTM timing measurements";
168 localizationSegment.onConnect();
169 commonVisu.connect(
getArvizClient(), debugObserver->getDebugObserver());
172 if (robotUnit.plugin->hasRobotUnitName())
174 robotUnit.plugin->waitUntilRobotUnitIsRunning();
177 robotUnit.reader.setTag(
getName());
178 robotUnit.writer.setTag(
getName());
180 descriptionSegment.onConnect(robotUnitPrx);
181 proprioceptionSegment.onConnect(robotUnitPrx);
183 robotUnit.reader.connect(
186 proprioceptionSegment.getRobotUnitProviderID().providerSegmentName);
187 robotUnit.writer.connect(*debugObserver);
188 robotUnit.writer.properties.robotUnitProviderID =
189 proprioceptionSegment.getRobotUnitProviderID();
192 [
this]() { robotUnit.reader.run(robotUnit.pollFrequency, *robotUnit.dataBuffer); },
193 "Robot Unit Reader");
197 robotUnit.writer.run(robotUnit.pollFrequency,
198 *robotUnit.dataBuffer,
200 localizationSegment);
202 "Robot State Writer");
204 startRobotUnitStream();
207 createRemoteGuiTab();
214 stopRobotUnitStream();
220 stopRobotUnitStream();
225 const std::string& robotName,
226 const ::Ice::Current& )
232 auto poseMap = localizationSegment.getRobotGlobalPoses(
timestamp);
234 const bool robotNameFound = simox::alg::contains_key(poseMap, robotName);
236 <<
"Robot with name " << robotName <<
" does not exist at or before timestamp "
238 <<
"Available robots are: " << simox::alg::get_keys(poseMap);
240 return {
new Pose(poseMap[robotName].matrix())};
249 RobotStateMemory::startRobotUnitStream()
260 ARMARX_WARNING <<
"Found inconsistency in running tasks. Restarting all!";
261 stopRobotUnitStream();
264 std::stringstream ss;
265 ss <<
"Getting sensor values for:" << std::endl;
266 for (
const auto& [name, dataEntry] : robotUnit.reader.
description.entries)
268 const std::string type =
270 ss <<
"\t" << name <<
" (type: '" << type <<
"')" << std::endl;
280 RobotStateMemory::stopRobotUnitStream()
283 robotUnit.dataBuffer->close();
284 robotUnit.reader.task->stop();
286 robotUnit.writer.task->stop();
291 RobotStateMemory::createRemoteGuiTab()
293 using namespace armarx::RemoteGui::Client;
297 tab.clearRobotStateWriterQueueButton.setLabel(
"Clear RobotStateWriter Queue");
298 root.
addChild(tab.clearRobotStateWriterQueueButton);
304 RobotStateMemory::RemoteGui_update()
308 if (tab.clearRobotStateWriterQueueButton.wasClicked())
310 clearRobotStateWriterQueue();
313 catch (
const std::exception& e)
315 ARMARX_WARNING <<
"RemoteGui_update: exception while handling button click: "
320 ARMARX_WARNING <<
"RemoteGui_update: unknown exception while handling button click.";
325 RobotStateMemory::clearRobotStateWriterQueue()
327 std::size_t dropped = 0;
330 if (not robotUnit.dataBuffer)
332 ARMARX_WARNING <<
"Cannot clear RobotStateWriter queue: data buffer is null.";
336 proprioception::RobotUnitData discarded;
339 boost::queue_op_status
status = boost::queue_op_status::empty;
342 status = robotUnit.dataBuffer->try_pull(discarded);
344 catch (
const std::exception& e)
346 ARMARX_WARNING <<
"Exception during queue try_pull after dropping " << dropped
347 <<
" entries: " << e.what() <<
". Stopping drain.";
352 ARMARX_WARNING <<
"Unknown exception during queue try_pull after dropping "
353 << dropped <<
" entries. Stopping drain.";
357 if (
status != boost::queue_op_status::success)
367 catch (
const std::exception& e)
369 ARMARX_WARNING <<
"clearRobotStateWriterQueue failed after dropping " << dropped
370 <<
" entries: " << e.what();
374 ARMARX_WARNING <<
"clearRobotStateWriterQueue failed with unknown exception after "
376 << dropped <<
" entries.";
#define ARMARX_REGISTER_COMPONENT_EXECUTABLE(ComponentT, applicationName)
static const std::string & GetProjectName()
static const Ice::StringSeq & GetProjectDependencies()
armarx::viz::Client & getArvizClient()
The CMakePackageFinder class provides an interface to the CMake Package finder capabilities.
Default component property definition container.
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
PluginT * addPlugin(const std::string prefix="", ParamsT &&... params)
std::string getName() const
Retrieve name of object.
void start()
Starts the thread.
bool isRunning() const
Retrieve running state of the thread.
void setDebugObserver(DebugObserverInterfacePrx observer)
Set an optional debug observer for timing measurements.
server::ltm::Memory & longtermMemory()
void setMemoryName(const std::string &memoryName)
MemoryToIceAdapter & iceAdapter()
void onInitComponent() override
Pure virtual hook for the subclass.
void onDisconnectComponent() override
Hook for subclass.
armarx::PoseBasePtr getGlobalRobotPose(Ice::Long timestamp, const std::string &robotName, const ::Ice::Current &) override
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Creates the property definition container.
void onConnectComponent() override
Pure virtual hook for the subclass.
void onExitComponent() override
Hook for subclass.
~RobotStateMemory() override
std::string getDefaultName() const override
Retrieve default name of component.
armarx::SimpleRunningTask ::pointer_type task
RobotUnitDataStreaming::DataStreamingDescription description
armarx::SimpleRunningTask ::pointer_type task
static Duration MicroSeconds(std::int64_t microSeconds)
Constructs a duration in microseconds.
bool robotUnitIsRunning() const
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_INFO
The normal logging level.
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
#define ARMARX_VERBOSE
The logging level for verbose information.
const simox::meta::EnumNames< DataEntryType > DataEntryNames
armarx::core::time::DateTime Time
::IceInternal::ProxyHandle<::IceProxy::armarx::RobotUnitInterface > RobotUnitInterfacePrx
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
SimpleRunningTask(Ts...) -> SimpleRunningTask< std::function< void(void)> >
void RemoteGui_startRunningTask()
void RemoteGui_createTab(std::string const &name, RemoteGui::Client::Widget const &rootWidget, RemoteGui::Client::Tab *tab)