RobotUnitReader.cpp
Go to the documentation of this file.
1#include "RobotUnitReader.h"
2
3#include <filesystem>
4#include <istream>
5
9
12
14{
15
17
18 void
21 const std::string& robotTypeName)
22 {
23 {
26 << "No converter for robot type '" << robotTypeName << "' available. \n"
27 << "Known are: " << proprioceptionConverterRegistry.getKeys();
28
29 config.loggingNames.push_back(properties.sensorPrefix);
30 receiver = robotUnitPlugin.startDataStreaming(config);
31 description = receiver->getDataDescription();
32 }
33
34 {
37 << "No converter for robot type '" << robotTypeName << "' available. \n"
38 << "Known are: " << exteroceptionConverterRegistry.getKeys();
39 }
40
41 {
42 // Thread-local copy of debug observer helper.
44 Logging::tag.tagName, debugObserverPlugin.getDebugObserver(), true);
45 }
46 }
47
48 void
49 RobotUnitReader::run(float pollFrequency, Queue& dataBuffer)
50 {
51 Metronome metronome(Frequency::HertzDouble(pollFrequency));
52
53 while (task and not task->isStopped())
54 {
55 auto start = std::chrono::high_resolution_clock::now();
56
57 if (std::optional<RobotUnitData> commit = fetchAndConvertLatestRobotUnitData())
58 {
59 debugObserver->setDebugObserverDatafield(
60 "RobotUnitReader | t commitTimestamp [us]",
61 commit->timestamp.toMicroSecondsSinceEpoch());
62
63 // will lock a mutex
64 dataBuffer.push(std::move(commit.value()));
65 }
66 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
67 std::chrono::high_resolution_clock::now() - start);
68 if (debugObserver)
69 {
70 debugObserver->setDebugObserverDatafield("RobotUnitReader | t run [ms]",
71 duration.count() / 1000.f);
72 debugObserver->sendDebugObserverBatch();
73 }
74
75 metronome.waitForNextTick();
76 }
77 }
78
79 std::optional<RobotUnitData>
81 {
83
84 RobotUnitData result;
85
86 std::optional<RobotUnitDataStreaming::TimeStep> data;
87 {
88 auto start = std::chrono::high_resolution_clock::now();
89 data = fetchLatestData();
91
92 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
93 std::chrono::high_resolution_clock::now() - start);
94 if (debugObserver)
95 {
96 debugObserver->setDebugObserverDatafield("RobotUnitReader | t Fetch [ms]",
97 duration.count() / 1000.f);
98 }
99 }
100 if (not data.has_value())
101 {
102 return std::nullopt;
103 }
104
105 ARMARX_DEBUG << "RobotUnitReader: Converting data current timestep to commit";
106 auto start = std::chrono::high_resolution_clock::now();
107
108
109 if (converterProprioception != nullptr)
110 {
111 result.proprioception = converterProprioception->convert(data.value(), description);
112 }
113
114 if (converterExteroception != nullptr)
115 {
116 result.exteroception = converterExteroception->convert(data.value(), description);
117 }
118
119 result.timestamp = Time(Duration::MicroSeconds(data->timestampUSec));
120
121 auto stop = std::chrono::high_resolution_clock::now();
122 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
123 ARMARX_DEBUG << "RobotUnitReader: The total time needed to convert the data to commit: "
124 << duration;
125
126 if (debugObserver)
127 {
128 debugObserver->setDebugObserverDatafield("RobotUnitReader | t Read+Group [ms]",
129 duration.count() / 1000.f);
130 }
131
132 return result;
133 }
134
135 std::optional<RobotUnitDataStreaming::TimeStep>
136 RobotUnitReader::fetchLatestData()
137 {
138 std::deque<RobotUnitDataStreaming::TimeStep>& data = receiver->getDataBuffer();
139 if (debugObserver)
140 {
141 debugObserver->setDebugObserverDatafield("RobotUnitReader | Buffer Size", data.size());
142 if (data.size())
143 {
144 debugObserver->setDebugObserverDatafield("RobotUnitReader | RT Timestamp USec",
145 data.back().timestampUSec);
146 debugObserver->setDebugObserverDatafield(
147 "RobotUnitReader | RT Timestamp Since Last Iteration",
148 data.back().timesSinceLastIterationUSec);
149 debugObserver->setDebugObserverDatafield(
150 "RobotUnitReader | Timestamp Arrived in RSM",
151 armarx::DateTime::Now().toMicroSecondsSinceEpoch());
152 }
153 }
154 if (data.empty())
155 {
156 return std::nullopt;
157 }
158 else
159 {
160 RobotUnitDataStreaming::TimeStep currentTimestep = data.back();
161 data.clear();
162 return currentTimestep;
163 }
164 }
165
166
167} // namespace armarx::armem::server::robot_state::proprioception
static DateTime Now()
Definition DateTime.cpp:51
Brief description of class DebugObserverHelper.
const DebugObserverInterfacePrx & getDebugObserver() const
static Frequency HertzDouble(double hertz)
Definition Frequency.cpp:30
void run(float pollFrequency, Queue &dataBuffer)
Reads data from handler and fills dataQueue.
void connect(armarx::plugins::RobotUnitComponentPlugin &robotUnitPlugin, armarx::plugins::DebugObserverComponentPlugin &debugObserverPlugin, const std::string &robotTypeName)
RobotUnitDataStreaming::DataStreamingDescription description
armarx::armem::server::robot_state::proprioception::Queue Queue
static Duration MicroSeconds(std::int64_t microSeconds)
Constructs a duration in microseconds.
Definition Duration.cpp:24
Simple rate limiter for use in loops to maintain a certain frequency given a clock.
Definition Metronome.h:57
Duration waitForNextTick() const
Wait and block until the target period is met.
Definition Metronome.cpp:27
Brief description of class DebugObserverComponentPlugin.
RobotUnitDataStreamingReceiverPtr startDataStreaming(const RobotUnitDataStreaming::Config &cfg)
#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_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
armarx::core::time::DateTime Time