PeriodicUpdateController.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2012-2025, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package RobotStateComponent::
19 * @author Samet Soenmez (uewtt at student dot kit dot edu)
20 * @date 2025t
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24
26
27#include <iomanip>
28
29#include <QLabel>
30#include <QTimer>
31#include <QLayout>
32#include <QBoxLayout>
33#include <QGroupBox>
34#include <QCheckBox>
35#include <QDoubleSpinBox>
36#include <QThread>
37
42
44{
46 MemoryViewerUIContext& uiContext,
47 std::shared_ptr<armem::gui::model::MemoryViewerModel> model)
48 {
49 _model = std::move(model);
50 _statusLabel = uiContext.statusLabel;
51 _memoryGroupBoxController = std::make_unique<MemoryGroupBoxController>(
52 uiContext,
53 _model
54 );
55
56 _periodicUpdateView = new armem::gui::view::PeriodicUpdateView();
57 uiContext.periodicUpdateViewLayout->insertWidget(0, _periodicUpdateView);
58
59 connect(_periodicUpdateView,
61 this,
62 [this]()
63 {
64 if (_model->connected()) {
65 _periodicUpdateView->showUpdatingLabel();
66 }
67 emit update();
68 });
69
70 connect(_periodicUpdateView,
72 this,
74
75 connect(_periodicUpdateView,
77 this,
79
80 connect(_periodicUpdateView,
82 this,
84
85 connect(_periodicUpdateView,
87 this,
89
90 connect(_memoryGroupBoxController->memoryGroupBoxView(),
92 this,
93 [this]()
94 {
95 _periodicUpdateView->toggleSplitButton();
96 });
97
98 startWorker();
99
100 }
101
103 {
104 if (_periodicUpdateWorkerThread)
105 {
106 _periodicUpdateWorkerThread->quit();
107 _periodicUpdateWorkerThread->wait();
108 }
109 }
110
111 void PeriodicUpdateController::startWorker()
112 {
113 _periodicUpdateWorkerThread = new QThread();
114 _periodicUpdateWorker = new PeriodicUpdateWorker(_model);
115 _periodicUpdateWorker->moveToThread(_periodicUpdateWorkerThread);
116
117 connect(_periodicUpdateWorkerThread,
118 &QThread::started,
119 _periodicUpdateWorker,
121
122 connect(_periodicUpdateWorkerThread,
123 &QThread::finished,
124 _periodicUpdateWorker,
126
127 connect(_periodicUpdateWorkerThread,
128 &QThread::finished,
129 _periodicUpdateWorker,
130 &QObject::deleteLater);
131
132 connect(_periodicUpdateWorkerThread,
133 &QThread::finished,
134 _periodicUpdateWorkerThread,
135 &QObject::deleteLater);
136
137 connect(_periodicUpdateWorker,
139 this,
141
142 connect(_periodicUpdateWorker,
144 this,
145 [this](){
146 if (_model->connected()) {
147 _periodicUpdateView->showUpdatingLabel();
148 }
149 });
150
151 connect(_periodicUpdateWorker,
153 this,
155
156 connect(this,
158 _periodicUpdateWorker,
160
161 connect(this,
163 _periodicUpdateWorker,
165
166 connect(this,
168 _periodicUpdateWorker,
170
171 connect(this,
173 _periodicUpdateWorker,
175
176 connect(this,
178 _periodicUpdateWorker,
180
181 connect(_periodicUpdateWorkerThread,
182 &QThread::started,
183 this,
185
186 connect(this,
188 _periodicUpdateWorker,
190
191 _periodicUpdateWorkerThread->start();
192
193 }
194
196 {
197 /* A QTimer can only be started and stopped within its own thread (the thread for which
198 * it has the greatest affinity). Since this method can be called from any thread, we
199 * need to take a detour through these signals, which can be emitted from any thread and
200 * will always be caught in the timer's native thread.
201 */
202 if (_periodicUpdateView->autoCheckBox()->isChecked())
203 {
205 }
206 }
207
209 {
210 _memoryGroupBoxController->memoryGroupBoxView()->tree()->collapseAll();
211 }
212
214 {
215 _periodicUpdateView->toggleSplitButton();
216 _memoryGroupBoxController->memoryGroupBoxView()->splitBox();
217 }
218
220 {
221 emit autoUpdateTimerIntervalSignal(_periodicUpdateView->getUpdateIntervalMs());
222 }
223
225 {
226 _periodicUpdateView->frequencySpinBox()->setEnabled(enabled);
227 if (enabled)
228 {
230 }
231 else
232 {
234 }
235 }
236
237 void
239 {
240 updateStatusLabel(errorCount);
241 _memoryGroupBoxController->updateMemoryTree();
242
243 _periodicUpdateView->hideUpdatingLabel();
244 }
245
246 void
247 PeriodicUpdateController::updateStatusLabel(int errorCount)
248 {
249 // Code to output status label information
250 if (_statusLabel and errorCount > 0)
251 {
252 auto now = std::chrono::system_clock::now();
253 auto in_time_t = std::chrono::system_clock::to_time_t(now);
254
255 std::stringstream ss;
256 ss << "Last update: " << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d %X");
257 ss << "\nThe query produced " << errorCount << " errors! Please check log.";
258
259 _statusLabel->setText(QString::fromStdString(ss.str()));
260 }
261 }
262
263 void
265 {
266 std::vector<std::string> activeMemoryNamesVec;
267 activeMemoryNamesVec.reserve(activeMemoryNames.size());
268 for (const QString& s : activeMemoryNames) {
269 activeMemoryNamesVec.push_back(s.toStdString());
270 }
271
272 TIMING_START(GuiUpdateAvailableMemories);
273 _memoryGroupBoxController
274 ->memoryGroupBoxView()
275 ->queryWidget()
276 ->update(activeMemoryNamesVec);
277
278 _memoryGroupBoxController
279 ->memoryGroupBoxView()
280 ->ltmWidget()
281 ->update(activeMemoryNamesVec);
282 TIMING_END_STREAM(GuiUpdateAvailableMemories, ARMARX_VERBOSE);
283 }
284
286 {
287 return _memoryGroupBoxController.get();
288 }
289}
controlls predictions, commits, LTM recording/storing
PeriodicUpdateController(MemoryViewerUIContext &uiContext, std::shared_ptr< armem::gui::model::MemoryViewerModel > model)
handles updating and periodically checks for new readers/writers and query results
void updateQueryWidget(QStringList activeMemoryNames)
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
#define TIMING_START(name)
Helper macro to do timing tests.
Definition TimeUtil.h:289
#define TIMING_END_STREAM(name, os)
Prints duration.
Definition TimeUtil.h:310