YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
mainwindow.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-FileCopyrightText: 2006-2010 RobotCub Consortium
4 * SPDX-License-Identifier: LGPL-2.1-or-later
5 */
6
7#include "mainwindow.h"
8#include "ui_mainwindow.h"
9
10#include "flowlayout.h"
11#include "jointitem.h"
12#include "partitem.h"
13
14#include <QToolBar>
15#include <QDebug>
16#include <QHBoxLayout>
17#include <QScrollArea>
18#include <QFont>
19#include <QFontMetrics>
20#include <QMessageBox>
21#include <QSettings>
22#include <QFileDialog>
23#include <QShortcut>
24#include <map>
25#include <cstdlib>
26#include <yarp/os/LogStream.h>
28
29MainWindow::MainWindow(QWidget *parent) :
30 QMainWindow(parent),
31 m_ui(new Ui::MainWindow)
32{
33 m_ui->setupUi(this);
34
35 QLocale::setDefault(QLocale::C);
36 m_tabPanel = nullptr;
37 m_sequenceActiveCount = 0;
38
39 setWindowTitle("Qt Robot Motor GUI V2.0");
41
42 m_sliderOpt = nullptr;
43
44 QString globalLabel("Global Joints Commands ");
45 m_globalToolBar = new QToolBar("Global Joints Commands", this);
47
48 QFont f = label1->font();
49 f.setBold(true);
50 label1->setFont(f);
51 m_globalToolBar->addWidget(label1)->setCheckable(false);
52
53
54 m_globalToolBar->addSeparator();
55 m_goAll = m_globalToolBar->addAction(QIcon(":/play-all.svg"), "Go All");
56 m_globalToolBar->addSeparator();
57 m_runAllSeq = m_globalToolBar->addAction(QIcon(":/images/runSequence.png"), "Run All Sequences (use joint speeds from Speed tab)");
58 m_runAllSeqTime = m_globalToolBar->addAction(QIcon(":/images/runSequenceTime.png"), "Run All Sequences (ignore Speed tab, produce coordinated movement using Timing)");
59 m_saveAllSeq = m_globalToolBar->addAction(QIcon(":/file-save.svg"), "Save All Sequences");
60 m_loadAllSeq = m_globalToolBar->addAction(QIcon(":/file-open.svg"), "Load All Sequences");
61 m_cycleAllSeq = m_globalToolBar->addAction(QIcon(":/images/cycleAllSequence.png"), "Cycle All Sequences (use joint speeds from Speed tab)");
62 m_cycleAllSeqTime = m_globalToolBar->addAction(QIcon(":/images/cycleAllSequenceTime.png"), "Cycle All Sequences (ignore Speed tab, produce coordinated movement using Timing)");
63 m_stopAllSeq = m_globalToolBar->addAction(QIcon(":/stop.svg"), "Stop All Sequences");
64 m_globalToolBar->addSeparator();
65 m_idleAllParts = m_globalToolBar->addAction(QIcon(":/idle.svg"), "Idle All Parts");
66 m_runAllParts = m_globalToolBar->addAction(QIcon(":/play.svg"), "Run All Parts");
67 m_homeAllParts = m_globalToolBar->addAction(QIcon(":/home.svg"), "Home All Parts");
68 m_globalToolBar->addSeparator();
69 m_script1 = m_globalToolBar->addAction(QIcon(":/action1.svg"), "Execute User Script1");
70 m_script2 = m_globalToolBar->addAction(QIcon(":/action2.svg"), "Execute User Script2");
71 addToolBar(m_globalToolBar);
72
73 QMenu *globalMenuCommands = m_ui->menuBar->addMenu("Global Joints Commands ");
74 globalMenuCommands->addAction(m_goAll);
75 globalMenuCommands->addSeparator();
76 globalMenuCommands->addAction(m_runAllSeq);
77 globalMenuCommands->addAction(m_runAllSeqTime);
78 globalMenuCommands->addAction(m_saveAllSeq);
79 globalMenuCommands->addAction(m_loadAllSeq);
80 globalMenuCommands->addAction(m_cycleAllSeq);
81 globalMenuCommands->addAction(m_cycleAllSeqTime);
82 globalMenuCommands->addAction(m_stopAllSeq);
83 globalMenuCommands->addSeparator();
84 globalMenuCommands->addAction(m_idleAllParts);
85 globalMenuCommands->addAction(m_runAllParts);
86 globalMenuCommands->addAction(m_homeAllParts);
87 //Looking for custom positions in the config file
89 //Positions have the following form: "customPosition_{NAME_OF_CUSTOM_POSITION}"
90 //To iterate on all groups, transform the finder into Bottle
91 yarp::os::Bottle ini(finder.toString());
92
93 std::map<std::string, yarp::os::Bottle> customPositions;
94
95 for (size_t index = 0; index < ini.size(); ++index) {
96 //Look for groups starting with "customPosition_"
97 yarp::os::Value item = ini.get(index);
98 if (!item.isList()) {
99 continue;
100 }
101 yarp::os::Bottle *subElement = item.asList();
102 //At least two elements and first should be string
103 if (!subElement
104 || subElement->size() < 2
105 || !subElement->get(0).isString()) {
106 continue;
107 }
108 //get first element
109 std::string key = subElement->get(0).asString();
110 std::string pattern = "customPosition_";
111 size_t subStringPosition = key.find(pattern);
112 if (subStringPosition != 0) {
113 continue; //not starting or not found
114 }
115
116 std::string customPositionName = key.substr(pattern.size());
117 customPositions.insert(std::map<std::string, yarp::os::Bottle>::value_type(customPositionName, subElement->tail()));
118 }
119
120 m_customPositionsAllParts.reserve(customPositions.size());
121 if (customPositions.size() > 0) {
122 //If there are customPositions create a submenu item
123 QMenu *customPositionsMenu = globalMenuCommands->addMenu(QIcon(":/home.svg"), "Custom positions");
124
125 unsigned keyIndex = 0;
126 for (std::map<std::string, yarp::os::Bottle>::const_iterator it(customPositions.begin()); it != customPositions.end(); ++it) {
127
128 QAction *newAction = customPositionsMenu->addAction(("Move all parts to " + it->first).c_str());
129 m_customPositionsAllParts.push_back(newAction);
130 //
131 const yarp::os::Bottle &position = it->second;
132
133 // Adding shortcut (to only the first 9 sequences)
134 if (keyIndex < 9) {
135 QKeySequence shortcut(Qt::CTRL + Qt::META + (Qt::Key_1 + keyIndex++));
136 newAction->setShortcut(shortcut);
137 newAction->setShortcutContext(Qt::ApplicationShortcut);
138 }
139
140 //copy position in the lambda
141 connect(newAction, &QAction::triggered, this, [this, position]{onHomeAllPartsToCustomPosition(position); });
142 }
143 }
144
145 globalMenuCommands->addSeparator();
146 globalMenuCommands->addAction(m_script1);
147 globalMenuCommands->addAction(m_script2);
148
149 connect(m_goAll, SIGNAL(triggered()), this, SLOT(onGoAll()));
150 connect(m_idleAllParts, SIGNAL(triggered()), this, SLOT(onIdleAllParts()));
151 connect(m_runAllParts, SIGNAL(triggered()), this, SLOT(onRunAllParts()));
152 connect(m_homeAllParts, SIGNAL(triggered()), this, SLOT(onHomeAllParts()));
153
154 connect(m_runAllSeq, SIGNAL(triggered()), this, SLOT(onRunAllSeq()));
155 connect(m_runAllSeqTime, SIGNAL(triggered()), this, SLOT(onRunTimeAllSeq()));
156 connect(m_cycleAllSeq, SIGNAL(triggered()), this, SLOT(onCycleAllSeq()));
157 connect(m_cycleAllSeqTime, SIGNAL(triggered()), this, SLOT(onCycleTimeAllSeq()));
158
159 connect(m_stopAllSeq, SIGNAL(triggered()), this, SLOT(onStopAllSeq()));
160 connect(m_loadAllSeq, SIGNAL(triggered()), this, SLOT(onLoadAllSeq()));
161 connect(m_saveAllSeq, SIGNAL(triggered()), this, SLOT(onSaveAllSeq()));
162
163 connect(m_script1, SIGNAL(triggered()), this, SLOT(onExecuteScript1()));
164 connect(m_script2, SIGNAL(triggered()), this, SLOT(onExecuteScript2()));
165
166 //addToolBarBreak();
167
168 m_partToolBar = new QToolBar("Current Part", this);
169 m_partToolBar->setMovable(true);
170 m_partToolBar->setFloatable(true);
171 m_partToolBar->setAllowedAreas(Qt::AllToolBarAreas);
172
173 m_partName = new QLabel("NONE");
174 f = m_partName->font();
175 f.setBold(true);
176 m_partName->setFont(f);
177
178 m_partToolBar->addWidget(m_partName)->setCheckable(false);
179
180 m_partToolBar->addSeparator();
181 openSequenceAction = m_partToolBar->addAction(QIcon(":/file-new.svg"), "Open Sequence Tab");
182 m_partToolBar->addSeparator();
183 m_runSinglePart = m_partToolBar->addAction(QIcon(":/play.svg"), "Run all joints of this part");
184 m_idleSinglePart = m_partToolBar->addAction(QIcon(":/idle.svg"), "Idle all joints of this part");
185 m_calibSinglePart = m_partToolBar->addAction(QIcon(":/images/calibrate.png"), "Calibrate all joints of this part");
186 m_homeSinglePart = m_partToolBar->addAction(QIcon(":/home.svg"), "Home all joints of this part");
187
188 m_customPositionsSinglePartToolbar.reserve(customPositions.size());
189 if (customPositions.size() > 0) {
190 for (std::map<std::string, yarp::os::Bottle>::const_iterator it(customPositions.begin()); it != customPositions.end(); ++it) {
191 QAction *newAction = m_partToolBar->addAction(QIcon(":/home.svg"), ("Move all joints of this part to " + it->first).c_str());
192 m_customPositionsSinglePartToolbar.push_back(newAction);
193 //
194 const yarp::os::Bottle &position = it->second;
195
196 //copy position in the lambda
197 connect(newAction, &QAction::triggered, this, [this, position]{onHomeSinglePartToCustomPosition(position); });
198 }
199 }
200
201 addToolBar(m_partToolBar);
202
203 m_currentPartMenu = m_ui->menuBar->addMenu("Current Part: ");
204 m_currentPartMenu->addAction(openSequenceAction);
205 m_currentPartMenu->addSeparator();
206 m_currentPartMenu->addAction(m_runSinglePart);
207 m_currentPartMenu->addAction(m_calibSinglePart);
208 m_currentPartMenu->addAction(m_homeSinglePart);
209 m_currentPartMenu->addAction(m_idleSinglePart);
210
211 m_customPositionsSinglePart.reserve(customPositions.size());
212 if (customPositions.size() > 0) {
213
214 //If there are customPositions create a submenu item
215 QMenu *customPositionsMenu = m_currentPartMenu->addMenu(QIcon(":/home.svg"), "Custom positions");
216
217 unsigned keyIndex = 0;
218 for (std::map<std::string, yarp::os::Bottle>::const_iterator it(customPositions.begin()); it != customPositions.end(); ++it) {
219 QAction *newAction = customPositionsMenu->addAction(("Move all joints of this part to " + it->first).c_str());
220 m_customPositionsSinglePartToolbar.push_back(newAction);
221 //
222 const yarp::os::Bottle &position = it->second;
223
224 // Adding shortcut (to only the first 9 sequences)
225 if (keyIndex < 9) {
226 QKeySequence shortcut(Qt::CTRL + Qt::ALT + Qt::META + (Qt::Key_1 + keyIndex++));
227 newAction->setShortcut(shortcut);
228 newAction->setShortcutContext(Qt::ApplicationShortcut);
229 }
230 //copy position in the lambda
231 connect(newAction, &QAction::triggered, this, [this, position]{onHomeSinglePartToCustomPosition(position); });
232
233 }
234 }
235
236
237 connect(openSequenceAction,SIGNAL(triggered()),this,SLOT(onOpenSequenceTab()));
238 connect(m_runSinglePart, SIGNAL(triggered()), this, SLOT(onRunSinglePart()));
239 connect(m_idleSinglePart, SIGNAL(triggered()), this, SLOT(onIdleSinglePart()));
240 connect(m_homeSinglePart, SIGNAL(triggered()), this, SLOT(onHomeSinglePart()));
241 connect(m_calibSinglePart, SIGNAL(triggered()), this, SLOT(onCalibSinglePart()));
242
243 QMenu *windows = m_ui->menuBar->addMenu("View");
244 QAction *viewGlobalToolbar = windows->addAction("Global Commands Toolbar");
245 QAction *viewPartToolbar = windows->addAction("Part Commands Toolbar");
246 QAction *viewSpeedValues = windows->addAction("View Speed Values");
247 QAction *viewCurrentValues = windows->addAction("View Current Values");
248 QAction *viewMotorPosition = windows->addAction("View Motor Position");
249 QAction *viewDutyCycles = windows->addAction("View Duty Cycles");
250 QAction *viewPositionTargetBox = windows->addAction("View Position Target Box");
251 QAction* viewPositionTargetValue = windows->addAction("View Position Target Value");
252 QAction *enableControlVelocity = windows->addAction("Enable Velocity Control");
253 QAction *enableControlVelocityDirect = windows->addAction("Enable Velocity Direct Control");
254 QAction *enableControlMixed = windows->addAction("Enable Mixed Control");
255 QAction *enableControlPositionDirect = windows->addAction("Enable Position Direct Control");
256 QAction *enableControlPWM = windows->addAction("Enable PWM Control");
257 QAction *enableControlCurrent = windows->addAction("Enable Current Control");
258 QAction *enableControlTorque = windows->addAction("Enable Torque Control");
259 QAction *sliderOptions = windows->addAction("Slider Options...");
260
261 viewGlobalToolbar->setCheckable(true);
262 viewPartToolbar->setCheckable(true);
263 viewSpeedValues->setCheckable(true);
264 viewCurrentValues->setCheckable(true);
265 viewMotorPosition->setCheckable(true);
266 viewDutyCycles->setCheckable(true);
267 enableControlVelocity->setCheckable(true);
268 enableControlVelocityDirect->setCheckable(true);
269 enableControlMixed->setCheckable(true);
270 enableControlPositionDirect->setCheckable(true);
271 enableControlPWM->setCheckable(true);
272 enableControlCurrent->setCheckable(true);
273 enableControlTorque->setCheckable(true);
274 viewPositionTargetBox->setCheckable(true);
275 viewPositionTargetValue->setCheckable(true);
276
277 QSettings settings("YARP","yarpmotorgui");
278 bool bViewGlobalToolbar = settings.value("GlobalToolVisible",true).toBool();
279 bool bViewPartToolbar = settings.value("PartToolVisible",true).toBool();
280 bool bSpeedValues = settings.value("SpeedValuesVisible",false).toBool();
281 bool bViewPositionTargetBox = settings.value("ViewPositionTargetBox", true).toBool();
282 bool bViewPositionTargetValue = settings.value("ViewPositionTargetValue", false).toBool();
283 bool bviewMotorPosition = settings.value("MotorPositionVisible", false).toBool();
284 bool bviewDutyCycles = settings.value("DutyCycleVisible", false).toBool();
285 bool bCurrentValues = settings.value("CurrentsVisible", false).toBool();
286
289 viewSpeedValues->setChecked(bSpeedValues);
292 viewDutyCycles->setChecked(bviewDutyCycles);
293 viewPositionTargetBox->setChecked(bViewPositionTargetBox);
294 viewPositionTargetValue->setChecked(bViewPositionTargetValue);
295 enableControlVelocity->setChecked(false);
296 enableControlVelocityDirect->setChecked(false);
297 enableControlMixed->setChecked(false);
298 enableControlPositionDirect->setChecked(false);
299 enableControlPWM->setChecked(false);
300 enableControlCurrent->setChecked(false);
301 enableControlTorque->setChecked(false);
302
303 m_globalToolBar->setVisible(bViewGlobalToolbar);
304 m_partToolBar->setVisible(bViewPartToolbar);
305
306 connect(viewGlobalToolbar,SIGNAL(triggered(bool)),this,SLOT(onViewGlobalToolbar(bool)));
307 connect(viewPartToolbar,SIGNAL(triggered(bool)),this,SLOT(onViewPartToolbar(bool)));
308 connect(viewSpeedValues,SIGNAL(triggered(bool)),this,SLOT(onViewSpeeds(bool)));
309 connect(viewCurrentValues, SIGNAL(triggered(bool)), this, SLOT(onViewCurrents(bool)));
310 connect(viewMotorPosition, SIGNAL(triggered(bool)), this, SLOT(onViewMotorPositions(bool)));
311 connect(viewDutyCycles, SIGNAL(triggered(bool)), this, SLOT(onViewDutyCycles(bool)));
312 connect(viewPositionTargetBox, SIGNAL(triggered(bool)), this, SLOT(onViewPositionTargetBox(bool)));
313 connect(viewPositionTargetValue, SIGNAL(triggered(bool)), this, SLOT(onViewPositionTargetValue(bool)));
314 connect(enableControlVelocity, SIGNAL(triggered(bool)), this, SLOT(onEnableControlVelocity(bool)));
315 connect(enableControlVelocityDirect, SIGNAL(triggered(bool)), this, SLOT(onEnableControlVelocityDirect(bool)));
316 connect(enableControlMixed, SIGNAL(triggered(bool)), this, SLOT(onEnableControlMixed(bool)));
317 connect(enableControlPositionDirect, SIGNAL(triggered(bool)), this, SLOT(onEnableControlPositionDirect(bool)));
318 connect(enableControlPWM, SIGNAL(triggered(bool)), this, SLOT(onEnableControlPWM(bool)));
319 connect(enableControlCurrent, SIGNAL(triggered(bool)), this, SLOT(onEnableControlCurrent(bool)));
320 connect(enableControlTorque, SIGNAL(triggered(bool)), this, SLOT(onEnableControlTorque(bool)));
321 connect(sliderOptions, SIGNAL(triggered()), this, SLOT(onSliderOptionsClicked()));
322
323 connect(this,SIGNAL(sig_internalClose()),this,SLOT(close()),Qt::QueuedConnection);
324
325 auto* lay = new QHBoxLayout();
326 lay->setMargin(0);
327 lay->setSpacing(0);
328 lay->setSizeConstraint(QLayout::SetMaximumSize);
329 m_ui->treeWidgetContainer->setLayout(lay);
330 m_modesTreeManager = new ModesTreeManager(lay, m_ui->treeWidgetContainer);
331 connect(m_modesTreeManager, SIGNAL(sig_jointClicked(int,int)), this, SLOT(onJointClicked(int,int)));
332 connect(m_modesTreeManager, SIGNAL(sig_partDoubleClicked(int)), this, SLOT(onPartDoubleClicked(int)));
333
334 m_timer.setInterval(200);
335 m_timer.setSingleShot(false);
336 connect(&m_timer, SIGNAL(timeout()), this, SLOT(onUpdate()), Qt::QueuedConnection);
337 m_timer.start();
338
339 const qreal blurRadius = 40.0;
340 const int glowDuration_msec = 2000;
341 m_glowEffect = new QGraphicsDropShadowEffect(this);
342 m_glowEffect->setOffset(.0);
343 m_glowEffect->setBlurRadius(blurRadius);
344 m_glowEffect->setColor(Qt::yellow);
345 m_glowTimer.setInterval(glowDuration_msec);
346 m_glowTimer.setSingleShot(true);
347 connect(&m_glowTimer, SIGNAL(timeout()), this, SLOT(onGlowTimerExpired()));
348}
349
351{
352 m_mutex.lock();
353
354 disconnect(&m_timer, SIGNAL(timeout()), this, SLOT(onUpdate()));
355 m_timer.stop();
356
357 onStopAllSeq();
358
359 if (m_tabPanel){
360 disconnect(m_tabPanel, SIGNAL(currentChanged(int)), this, SLOT(onCurrentPartChanged(int)));
361 for (int i = 0; i<m_tabPanel->count(); i++)
362 {
363 if (m_tabPanel->widget(i))
364 {
365 delete m_tabPanel->widget(i);
366 }
367 }
368 delete m_tabPanel;
369 m_tabPanel = nullptr;
370 }
371
372 delete m_ui;
373
374 m_mutex.unlock();
375}
376
378{
380 this->close();
381}
382
383void MainWindow::onSequenceActivated()
384{
385 m_sequenceActiveCount++;
386 m_goAll->setEnabled(false);
387 m_runAllSeq->setEnabled(false);
388 m_runAllSeqTime->setEnabled(false);
389 m_saveAllSeq->setEnabled(false);
390 m_loadAllSeq->setEnabled(false);
391 m_cycleAllSeq->setEnabled(false);
392 m_cycleAllSeqTime->setEnabled(false);
393 m_runAllParts->setEnabled(false);
394 m_idleAllParts->setEnabled(false);
395 m_homeAllParts->setEnabled(false);
396}
397
398void MainWindow::onSequenceStopped()
399{
400 m_sequenceActiveCount--;
401 if (m_sequenceActiveCount <= 0)
402 {
403 m_sequenceActiveCount = 0;
404 m_goAll->setEnabled(true);
405 m_runAllSeq->setEnabled(true);
406 m_runAllSeqTime->setEnabled(true);
407 m_saveAllSeq->setEnabled(true);
408 m_loadAllSeq->setEnabled(true);
409 m_cycleAllSeq->setEnabled(true);
410 m_cycleAllSeqTime->setEnabled(true);
411 m_runAllParts->setEnabled(true);
412 m_idleAllParts->setEnabled(true);
413 m_homeAllParts->setEnabled(true);
414 }
415}
416
417
418void MainWindow::onViewGlobalToolbar(bool val)
419{
420 QSettings settings("YARP","yarpmotorgui");
421 settings.setValue("GlobalToolVisible",val);
422 if(!val){
423 m_globalToolBar->hide();
424 }else{
425 m_globalToolBar->show();
426 }
427
428}
429
430void MainWindow::onViewPartToolbar(bool val)
431{
432 QSettings settings("YARP","yarpmotorgui");
433 settings.setValue("PartToolVisible",val);
434 if(!val){
435 m_partToolBar->hide();
436 }else{
437 m_partToolBar->show();
438 }
439}
440
441void MainWindow::onEnableControlVelocity(bool val)
442{
444}
445
446void MainWindow::onEnableControlVelocityDirect(bool val)
447{
449}
450
451void MainWindow::onEnableControlMixed(bool val)
452{
454}
455
456void MainWindow::onEnableControlPositionDirect(bool val)
457{
459}
460
461void MainWindow::onEnableControlPWM(bool val)
462{
464}
465
466void MainWindow::onEnableControlCurrent(bool val)
467{
469}
470
471void MainWindow::onEnableControlTorque(bool val)
472{
474}
475
476void MainWindow::onSliderOptionsClicked()
477{
478 m_sliderOpt = new sliderOptions(this);
479
480 m_sliderOpt->exec();
481
482 delete m_sliderOpt;
483 m_sliderOpt = nullptr;
484}
485
486void MainWindow::onViewSpeeds(bool val)
487{
488 QSettings settings("YARP","yarpmotorgui");
489 settings.setValue("SpeedValuesVisible",val);
490
492}
493
494void MainWindow::onViewCurrents(bool val)
495{
496 QSettings settings("YARP", "yarpmotorgui");
497 settings.setValue("CurrentValuesVisible", val);
498
500}
501
502void MainWindow::onViewMotorPositions(bool val)
503{
504 QSettings settings("YARP", "yarpmotorgui");
505 settings.setValue("MotorPositionVisible", val);
506
508}
509
510void MainWindow::onViewDutyCycles(bool val)
511{
512 QSettings settings("YARP", "yarpmotorgui");
513 settings.setValue("DutyCyclesVisible", val);
514
516}
517
518void MainWindow::onViewPositionTargetBox(bool val)
519{
520 QSettings settings("YARP", "yarpmotorgui");
521 settings.setValue("ViewPositionTarget", val);
522
524}
525
526void MainWindow::onViewPositionTargetValue(bool val)
527{
528 QSettings settings("YARP", "yarpmotorgui");
529 settings.setValue("ViewPositionTarget", val);
530
532}
533
534void MainWindow::onSetPosSliderOptionMW(int choice, double val, int digits)
535{
537}
538void MainWindow::onSetVelSliderOptionMW(int choice, double val, int digits)
539{
541}
542void MainWindow::onSetAccSliderOptionMW(int choice, double val, int digits)
543{
545}
546void MainWindow::onSetTrqSliderOptionMW(int choice, double val, int digits)
547{
549}
550void MainWindow::onSetCurSliderOptionMW(int choice, double val, int digits)
551{
553}
554
555void MainWindow::onJointClicked(int partIndex, int jointIndex)
556{
557 if (!m_tabPanel){
558 return;
559 }
560
561 m_tabPanel->setCurrentIndex(partIndex);
562 auto* scroll = static_cast<QScrollArea*>(m_tabPanel->widget(partIndex));
563 auto* part = static_cast<PartItem*>(scroll->widget());
564 auto* jointWidget = part->getJointWidget(jointIndex);
565 scroll->ensureWidgetVisible(jointWidget);
566 m_glowEffect->setEnabled(false);
567 jointWidget->setGraphicsEffect(m_glowEffect);
568 m_glowEffect->setEnabled(true);
569 m_glowTimer.start();
570}
571
572void MainWindow::onGlowTimerExpired()
573{
574 m_glowEffect->setEnabled(false);
575}
576
577void MainWindow::onPartDoubleClicked(int partIndex)
578{
579 if (!m_tabPanel){
580 return;
581 }
582
583 m_tabPanel->setCurrentIndex(partIndex);
584}
585
587{
588
589 m_mutex.lock();
590
591 this->setVisible(false);
592
593 disconnect(&m_timer, SIGNAL(timeout()), this, SLOT(onUpdate()));
594 m_timer.stop();
595
596 onStopAllSeq();
597
598 if (m_tabPanel){
599 disconnect(m_tabPanel, SIGNAL(currentChanged(int)), this, SLOT(onCurrentPartChanged(int)));
600 for (int i = 0; i<m_tabPanel->count(); i++){
601 if (m_tabPanel->widget(i)){
602 delete m_tabPanel->widget(i);
603 }
604 }
605 delete m_tabPanel;
606 m_tabPanel = nullptr;
607 }
608
609 m_mutex.unlock();
610
611 QMainWindow::closeEvent(event);
612
613}
614
615
616
617
618bool MainWindow::init(std::vector<std::string> enabledParts,
622 bool enable_calib_all,
623 std::string rcb_protocol)
624{
625 m_tabPanel = new QTabWidget(m_ui->mainContainer);
626
628 {
629 m_calibSinglePart->setEnabled(false);
630 }
631
632 int errorCount = 0;
633 QScrollArea *scroll = nullptr;
634 PartItem *part = nullptr;
635 m_finder = finder;
636 m_user_script1 = m_finder.find("script1").asString();
637 m_user_script2 = m_finder.find("script2").asString();
638
639 struct robot_type
640 {
641 std::string robot_name_without_slash;
642 };
643
644 struct part_type
645 {
646 std::string robot_name_without_slash;
647 std::string robot_name;
648 std::string complete_name;
649 std::string part_name_without_slash;
650 int partindex;
651 };
652
653 std::map<std::string, robot_type> robots;
654 std::map<std::string, part_type> parts;
655
656 for (int i = 0; i < enabledParts.size(); i++)
657 {
658 std::string ss = enabledParts.at(i);
659 size_t b1 = ss.find('/');
660 size_t b2 = ss.find('/', b1 + 1);
661 if (b1 == std::string::npos ||
662 b2 == std::string::npos)
663 {
664 yError() << "Invalid parts name, missing / char?";
665 return false;
666 }
667 std::string cur_robot_name = ss.substr(b1, b2 - b1);
668 auto it = robots.find(cur_robot_name);
669 if (it == robots.end())
670 {
671 robot_type r;
672 r.robot_name_without_slash = cur_robot_name;
673 if (r.robot_name_without_slash[0] == '/') {
674 r.robot_name_without_slash.erase(0, 1);
675 }
677 }
678 part_type p;
679 p.partindex = i;
680 p.complete_name = enabledParts.at(i);
681 p.part_name_without_slash = ss.substr(b2);
682 if (p.part_name_without_slash[0] == '/') {
683 p.part_name_without_slash.erase(0, 1);
684 }
685 p.robot_name = cur_robot_name;
686 p.robot_name_without_slash = robots[cur_robot_name].robot_name_without_slash;
687 parts[ss.substr(b2)] = p;
688 }
689
690 for (auto& robot : robots)
691 {
692 m_modesTreeManager->addRobot(robot.first.c_str());
693 }
694
695 for (auto& i_parts : parts)
696 {
697 //JointItem *item = new JointItem();
698 //layout->addWidget(item);
699 scroll = new QScrollArea(m_tabPanel);
700 scroll->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
701 scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
702 scroll->setWidgetResizable(true);
703 std::string part_name = i_parts.first;
704 std::string robot_name = i_parts.second.robot_name;
705 std::string robot_name_without_slash = i_parts.second.robot_name_without_slash;
706 std::string part_name_without_slash = i_parts.second.part_name_without_slash;
707 int part_id = i_parts.second.partindex;
709
710 if(part && !part->getInterfaceError())
711 {
712 connect(part,SIGNAL(sequenceActivated()),this,SLOT(onSequenceActivated()));
713 connect(part,SIGNAL(sequenceStopped()),this,SLOT(onSequenceStopped()));
714 connect(this,SIGNAL(sig_viewSpeedValues(bool)),part,SLOT(onViewSpeedValues(bool)));
715 connect(this, SIGNAL(sig_viewCurrentValues(bool)), part, SLOT(onViewCurrentValues(bool)));
716 connect(this, SIGNAL(sig_viewMotorPositions(bool)), part, SLOT(onViewMotorPositions(bool)));
717 connect(this, SIGNAL(sig_viewDutyCycles(bool)), part, SLOT(onViewDutyCycles(bool)));
718 connect(this, SIGNAL(sig_setPosSliderOptionMW(int,double,int)), part, SLOT(onSetPosSliderOptionPI(int,double,int)));
719 connect(this, SIGNAL(sig_setVelSliderOptionMW(int,double,int)), part, SLOT(onSetVelSliderOptionPI(int,double,int)));
720 connect(this, SIGNAL(sig_setAccSliderOptionMW(int,double,int)), part, SLOT(onSetAccSliderOptionPI(int,double,int)));
721 connect(this, SIGNAL(sig_setTrqSliderOptionMW(int,double,int)), part, SLOT(onSetTrqSliderOptionPI(int,double,int)));
722 connect(this, SIGNAL(sig_setCurSliderOptionMW(int,double,int)), part, SLOT(onSetCurSliderOptionPI(int,double,int)));
723 connect(this, SIGNAL(sig_viewPositionTargetBox(bool)), part, SLOT(onViewPositionTargetBox(bool)));
724 connect(this, SIGNAL(sig_viewPositionTargetValue(bool)), part, SLOT(onViewPositionTargetValue(bool)));
725 connect(this, SIGNAL(sig_enableControlVelocity(bool)), part, SLOT(onEnableControlVelocity(bool)));
726 connect(this, SIGNAL(sig_enableControlMixed(bool)), part, SLOT(onEnableControlMixed(bool)));
727 connect(this, SIGNAL(sig_enableControlPositionDirect(bool)), part, SLOT(onEnableControlPositionDirect(bool)));
728 connect(this, SIGNAL(sig_enableControlPWM(bool)), part, SLOT(onEnableControlPWM(bool)));
729 connect(this, SIGNAL(sig_enableControlCurrent(bool)), part, SLOT(onEnableControlCurrent(bool)));
730 connect(this, SIGNAL(sig_enableControlTorque(bool)), part, SLOT(onEnableControlTorque(bool)));
731 connect(this, SIGNAL(sig_enableControlVelocityDirect(bool)), part, SLOT(onEnableControlVelocityDirect(bool)));
732
733 scroll->setWidget(part);
734 int tabIndex = m_tabPanel->addTab(scroll, part_name.c_str());
735 if (part_id == 0)
736 {
737 QString auxName = part_name.c_str();
738 auxName.replace(0, 1, QString(part_name.c_str()).at(0).toUpper());
739 m_currentPartMenu->setTitle(QString("%1 Commands ").arg(auxName));
740 this->m_partName->setText(QString("%1 Commands ").arg(auxName));
741 }
742
743 m_modesTreeManager->addRobotPart(robot_name, part_name, tabIndex, part);
744 }
745 else
746 {
747 if(part)
748 {
749 delete part;
750 part = nullptr;
751 }
752 if(scroll)
753 {
754 delete scroll;
755 scroll = nullptr;
756 }
757 errorCount++;
758 }
759 }
760
761 if((unsigned int)errorCount == parts.size())
762 {
763 return false;
764 }
765
766 auto* lay = new QHBoxLayout();
767 lay->setMargin(0);
768 lay->setSpacing(0);
769 m_ui->mainContainer->setLayout(lay);
770 m_ui->mainContainer->layout()->addWidget(m_tabPanel);
771 connect(m_tabPanel, SIGNAL(currentChanged(int)), this, SLOT(onCurrentPartChanged(int)));
772
773 QSettings settings("YARP","yarpmotorgui");
774 bool speedVisible = settings.value("SpeedValuesVisible",false).toBool();
775 bool motorPosVisible = settings.value("MotorPositionVisible", false).toBool();
776 bool currentVisible = settings.value("CurrentsVisible", false).toBool();
777 bool dutyVisible = settings.value("DutyCyclesVisible", false).toBool();
778
779 onViewSpeeds(speedVisible);
780 onViewCurrents(currentVisible);
781 onViewMotorPositions(motorPosVisible);
782 onViewDutyCycles(dutyVisible);
783 return true;
784}
785
786
787void MainWindow::onCurrentPartChanged(int index)
788{
789 if(index < 0){
790 return;
791 }
792 QString partName = m_tabPanel->tabText(index);
793
794 QString auxName = partName;
795 auxName.replace(0,1,partName.at(0).toUpper());
796 m_currentPartMenu->setTitle(QString("%1 Commands").arg(auxName));
797 this->m_partName->setText(QString("%1 Commands").arg(auxName));
798
799 auto* scroll = (QScrollArea *)m_tabPanel->widget(index);
800 auto* part = (PartItem*)scroll->widget();
801 if(!part){
802 return;
803 }
804
805 part->resizeWidget(part->width());
806
807}
808
809void MainWindow::onCalibSinglePart()
810{
811 if (!m_tabPanel){
812 return;
813 }
814
815 auto* scroll = (QScrollArea *)m_tabPanel->currentWidget();
816 auto* part = (PartItem*)scroll->widget();
817 if(!part){
818 return;
819 }
820
821 if (QMessageBox::question(this, "Question", QString("Do you really want to recalibrate all joints of this part?")) == QMessageBox::Yes)
822 {
823 part->calibratePart(); // Error message is thrown inside
824 }
825}
826
827void MainWindow::onExecuteScript1()
828{
829 if (m_user_script1 == "")
830 {
831 QMessageBox::information(this, "Info", QString("user script1 not specified. use --script1 option"));
832 return;
833 }
834
835 if (QMessageBox::question(this, "Question", QString("Do you really want to execute user script1?")) == QMessageBox::Yes)
836 {
837 if (system(nullptr))
838 {
839 std::string script1_file = this->m_finder.findFileByName(m_user_script1);
840 if (script1_file != "")
841 {
842 int r = system(script1_file.c_str());
843 yDebug() << "yarpmotorgui_script1 returned value:" << r;
844 }
845 else
846 {
847 QMessageBox::information(this, "Info", QString("Unable to find script1 file"));
848 }
849 }
850 else
851 {
852 QMessageBox::information(this, "Info", QString("System is unable to run script1"));
853 }
854 }
855}
856
857void MainWindow::onExecuteScript2()
858{
859 if (m_user_script2 == "")
860 {
861 QMessageBox::information(this, "Info", QString("user script2 not specified. use --script2 option"));
862 return;
863 }
864
865 if (QMessageBox::question(this, "Question", QString("Do you really want to execute user script2?")) == QMessageBox::Yes)
866 {
867 if (system(nullptr))
868 {
869 std::string script2_file = this->m_finder.findFileByName(m_user_script2);
870 if (script2_file != "")
871 {
872 int r = system(script2_file.c_str());
873 yDebug() << "yarpmotorgui_script2 returned value:" << r;
874 }
875 else
876 {
877 QMessageBox::information(this, "Info", QString("Unable to find script2 file"));
878 }
879 }
880 else
881 {
882 QMessageBox::information(this, "Info", QString("System is unable to run script2"));
883 }
884 }
885}
886
887void MainWindow::onHomeSinglePart()
888{
889 if (QMessageBox::question(this, "Question", "Do you really want to home all joints of this part?") != QMessageBox::Yes){
890 return;
891 }
892
893 if (!m_tabPanel){
894 return;
895 }
896
897 auto* scroll = (QScrollArea *)m_tabPanel->currentWidget();
898 auto* part = (PartItem*)scroll->widget();
899 if (!part){
900 return;
901 }
902
903 part->homePart();
904}
905
906void MainWindow::onHomeAllParts()
907{
908 if (QMessageBox::question(this, "Question", "Do you really want to home all parts?") != QMessageBox::Yes){
909 return;
910 }
911
912 if (!m_tabPanel){
913 return;
914 }
915
916 for (int i = 0; i<m_tabPanel->count(); i++)
917 {
918 auto* scroll = (QScrollArea *)m_tabPanel->widget(i);
919 auto* part = (PartItem*)scroll->widget();
920 if (!part)
921 {
922 continue;
923 }
924
925 part->homePart();
926 }
927}
928
929void MainWindow::onHomeAllPartsToCustomPosition(const yarp::os::Bottle& positionElement)
930{
931 if (QMessageBox::question(this, "Question", "Do you really want to home all parts?") != QMessageBox::Yes){
932 return;
933 }
934
935 if (!m_tabPanel){
936 return;
937 }
938
939 for (int i = 0; i<m_tabPanel->count(); i++)
940 {
941 auto* scroll = (QScrollArea *)m_tabPanel->widget(i);
942 auto* part = (PartItem*)scroll->widget();
943 QString currName = QString("/%1/%2").arg(QString(m_finder.find("robot").asString().c_str())).arg(QString(part->getPartName().c_str()));
944 bool partPresent = positionElement.check(currName.toStdString() + "_Position") && positionElement.check(currName.toStdString() + "_Velocity");
945 if(!part || ! partPresent)
946 {
947 continue;
948 }
949 part->homeToCustomPosition(positionElement);
950 }
951}
952
953void MainWindow::onHomeSinglePartToCustomPosition(const yarp::os::Bottle& positionElement)
954{
955 if (QMessageBox::question(this, "Question", "Do you really want to home all joints of this part?") != QMessageBox::Yes){
956 return;
957 }
958
959 if (!m_tabPanel){
960 return;
961 }
962
963 auto* scroll = (QScrollArea *)m_tabPanel->currentWidget();
964 auto* part = (PartItem*)scroll->widget();
965 if(!part){
966 return;
967 }
968
969 part->homeToCustomPosition(positionElement);
970}
971
972void MainWindow::onIdleSinglePart()
973{
974 if (!m_tabPanel){
975 return;
976 }
977
978 auto* scroll = (QScrollArea *)m_tabPanel->currentWidget();
979 auto* part = (PartItem*)scroll->widget();
980 if(!part){
981 return;
982 }
983
984 part->idlePart();
985}
986
987void MainWindow::onCycleTimeAllSeq()
988{
989 if (!m_tabPanel){
990 return;
991 }
992
994
995 for (int i = 0; i<m_tabPanel->count(); i++){
996 auto* scroll = (QScrollArea *)m_tabPanel->widget(i);
997 auto* part = (PartItem*)scroll->widget();
998 if(!part){
999 continue;
1000 }
1001
1002 bool done = part->checkAndCycleTimeAllSeq();
1003 if(!done){
1004 QString qs = QString(part->getPartName().c_str());
1005 notSelectedParts.append(QString("- %1\n").arg(qs));
1006 }
1007 }
1008 if(!notSelectedParts.isEmpty()){
1009 QMessageBox::critical(this,"Error", QString("Load a valid sequence before performing this action for these parts:\n%1").arg(notSelectedParts));
1010 }
1011}
1012
1013void MainWindow::onCycleAllSeq()
1014{
1015 if (!m_tabPanel){
1016 return;
1017 }
1018
1020
1021 for (int i = 0; i<m_tabPanel->count(); i++){
1022 auto* scroll = (QScrollArea *)m_tabPanel->widget(i);
1023 auto* part = (PartItem*)scroll->widget();
1024 if(!part){
1025 continue;
1026 }
1027
1028 bool done = part->checkAndCycleAllSeq();
1029 if(!done){
1030 notSelectedParts.append(QString("- %1\n").arg(QString(part->getPartName().c_str())));
1031 }
1032 }
1033 if(!notSelectedParts.isEmpty()){
1034 QMessageBox::critical(this,"Error", QString("Load a valid sequence before performing this action for these parts:\n%1").arg(notSelectedParts));
1035 }
1036}
1037
1038void MainWindow::onRunAllSeq()
1039{
1040 if (!m_tabPanel){
1041 return;
1042 }
1043
1045
1046 for (int i = 0; i<m_tabPanel->count(); i++){
1047 auto* scroll = (QScrollArea *)m_tabPanel->widget(i);
1048 auto* part = (PartItem*)scroll->widget();
1049 if(!part){
1050 continue;
1051 }
1052
1053 bool done = part->checkAndRunAllSeq();
1054 if(!done){
1055 QString qs = QString(part->getPartName().c_str());
1056 notSelectedParts.append(QString("- %1\n").arg(qs));
1057 }
1058 }
1059 if(!notSelectedParts.isEmpty()){
1060 QMessageBox::critical(this,"Error", QString("Load a valid sequence before performing this action for these parts:\n%1").arg(notSelectedParts));
1061 }
1062}
1063
1064
1065void MainWindow::onRunTimeAllSeq()
1066{
1067 if (!m_tabPanel){
1068 return;
1069 }
1070
1072
1073 for (int i = 0; i<m_tabPanel->count(); i++){
1074 auto* scroll = (QScrollArea *)m_tabPanel->widget(i);
1075 auto* part = (PartItem*)scroll->widget();
1076 if(!part){
1077 continue;
1078 }
1079
1080 bool done = part->checkAndRunTimeAllSeq();
1081 if(!done){
1082 QString qs = QString(part->getPartName().c_str());
1083 notSelectedParts.append(QString("- %1\n").arg(qs));
1084 }
1085 }
1086 if(!notSelectedParts.isEmpty()){
1087 QMessageBox::critical(this,"Error", QString("Load a valid sequence before performing this action for these parts:\n%1").arg(notSelectedParts));
1088 }
1089}
1090
1091void MainWindow::onLoadAllSeq()
1092{
1093 if (!m_tabPanel){
1094 return;
1095 }
1096
1097
1098 for (int i = 0; i<m_tabPanel->count(); i++){
1099 auto* scroll = (QScrollArea *)m_tabPanel->widget(i);
1100 auto* part = (PartItem*)scroll->widget();
1101 if(!part){
1102 continue;
1103 }
1104
1105 part->loadSequence();
1106
1107 }
1108}
1109
1110void MainWindow::onSaveAllSeq()
1111{
1112 if (!m_tabPanel){
1113 return;
1114 }
1115
1116 QString fileName = QFileDialog::getSaveFileName(this, QString("Save Sequence for all parts as:"), QDir::homePath());
1117
1118 for (int i = 0; i<m_tabPanel->count(); i++)
1119 {
1120 auto* scroll = (QScrollArea *)m_tabPanel->widget(i);
1121 auto* part = (PartItem*)scroll->widget();
1122 if(!part)
1123 {
1124 continue;
1125 }
1126 part->saveSequence(fileName);
1127 part->closeSequenceWindow();
1128 }
1129}
1130
1131void MainWindow::onStopAllSeq()
1132{
1133 if (!m_tabPanel){
1134 return;
1135 }
1136
1137
1138 for (int i = 0; i<m_tabPanel->count(); i++){
1139 auto* scroll = (QScrollArea *)m_tabPanel->widget(i);
1140 auto* part = (PartItem*)scroll->widget();
1141 if(!part){
1142 continue;
1143 }
1144
1145 part->stopSequence();
1146
1147 }
1148
1149 }
1150
1151void MainWindow::onGoAll()
1152{
1153 if (!m_tabPanel){
1154 return;
1155 }
1156
1158
1159 for (int i = 0; i<m_tabPanel->count(); i++){
1160 auto* scroll = (QScrollArea *)m_tabPanel->widget(i);
1161 auto* part = (PartItem*)scroll->widget();
1162 if(!part){
1163 continue;
1164 }
1165
1166 bool done = part->checkAndGo();
1167 if(!done){
1168 QString qs = QString(part->getPartName().c_str());
1169 notSelectedParts.append(QString("- %1\n").arg(qs));
1170 }
1171 }
1172
1173 if(!notSelectedParts.isEmpty()){
1174 QMessageBox::critical(this,"Error", QString("Select a valid entry in the table before performing a movement for these parts:\n%1").arg(notSelectedParts));
1175 }
1176
1177}
1178
1179void MainWindow::onIdleAllParts()
1180{
1181 if (QMessageBox::question(this, "Question", "Do you really want to idle all parts?") != QMessageBox::Yes){
1182 return;
1183 }
1184
1185 if (!m_tabPanel){
1186 return;
1187 }
1188
1189 for (int i = 0; i<m_tabPanel->count(); i++)
1190 {
1191 auto* scroll = (QScrollArea *)m_tabPanel->widget(i);
1192 auto* part = (PartItem*)scroll->widget();
1193 if (!part){
1194 continue;
1195 }
1196
1197 part->idlePart();
1198 }
1199}
1200
1201void MainWindow::onRunAllParts()
1202{
1203 if (!m_tabPanel){
1204 return;
1205 }
1206
1207 for (int i = 0; i<m_tabPanel->count(); i++){
1208 auto* scroll = (QScrollArea *)m_tabPanel->widget(i);
1209 auto* part = (PartItem*)scroll->widget();
1210 if(!part){
1211 continue;
1212 }
1213
1214 part->runPart();
1215 }
1216}
1217
1218void MainWindow::onRunSinglePart()
1219{
1220 if (!m_tabPanel){
1221 return;
1222 }
1223
1224 auto* scroll = (QScrollArea *)m_tabPanel->currentWidget();
1225 auto* part = (PartItem*)scroll->widget();
1226 if(!part){
1227 return;
1228 }
1229
1230 part->runPart();
1231}
1232
1233void MainWindow::onOpenSequenceTab()
1234{
1235 if (!m_tabPanel){
1236 return;
1237 }
1238
1239 auto* scroll = (QScrollArea *)m_tabPanel->currentWidget();
1240 auto* part = (PartItem*)scroll->widget();
1241 if(!part){
1242 return;
1243 }
1244 part->openSequenceWindow();
1245}
1246
1247
1248
1249void MainWindow::onUpdate()
1250{
1251 if (!m_tabPanel){
1252 return;
1253 }
1254 m_mutex.lock();
1255
1256 auto* scroll = (QScrollArea *)m_tabPanel->currentWidget();
1257 if(!scroll){
1258 m_mutex.unlock();
1259 return;
1260 }
1261 auto* currentPart = (PartItem*)scroll->widget();
1262 if(!currentPart){
1263 m_mutex.unlock();
1264 return;
1265 }
1266 for (int i = 0; i<m_tabPanel->count(); i++)
1267 {
1268 auto* tabScroll = (QScrollArea *)m_tabPanel->widget(i);
1269 auto* item = (PartItem*)tabScroll->widget();
1270 item->updateControlMode();
1271 m_modesTreeManager->updateRobotPart(i);
1272 if(item == currentPart)
1273 {
1274 if (item->updatePart() == false)
1275 {
1276 //this part is disconnected!
1277 }
1278 }
1279 }
1280 m_mutex.unlock();
1281}
#define yError(...)
Definition Log.h:361
#define yDebug(...)
Definition Log.h:275
int SIGNAL(int pid, int signum)
MainWindow class.
Definition display.h:22
void sig_enableControlMixed(bool)
void sig_enableControlPWM(bool)
void closeEvent(QCloseEvent *event) override
void sig_setAccSliderOptionMW(int, double, int)
void sig_enableControlVelocityDirect(bool)
void sig_setVelSliderOptionMW(int, double, int)
void sig_setPosSliderOptionMW(int, double, int)
void sig_enableControlTorque(bool)
void sig_enableControlVelocity(bool)
void init(yarp::os::Property config)
Init the application with the current configuration.
MainWindow(const yarp::os::ResourceFinder &rf, yarp::dev::IBattery *ibat, QWidget *parent=0, double refresh_period=10.0)
Definition display.cpp:186
void sig_viewPositionTargetValue(bool)
void sig_viewSpeedValues(bool)
void sig_enableControlPositionDirect(bool)
void sig_viewMotorPositions(bool)
void sig_internalClose()
void sig_viewDutyCycles(bool)
void sig_enableControlCurrent(bool)
void sig_viewCurrentValues(bool)
void sig_setCurSliderOptionMW(int, double, int)
void sig_setTrqSliderOptionMW(int, double, int)
void sig_viewPositionTargetBox(bool)
void updateRobotPart(int index)
void addRobotPart(const std::string &robotName, const std::string &partName, int partIndex, PartItem *part)
void addRobot(const std::string &robotName)
bool getInterfaceError()
Definition partitem.cpp:511
A simple collection of objects that can be described and transmitted in a portable way.
Definition Bottle.h:65
A mini-server for performing network communication in the background.
Helper class for finding config files and other external resources.
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
static ResourceFinder & getResourceFinderSingleton()
Access a ResourceFinder singleton whose lifetime will match that of the YARP library.
std::string findFileByName(const std::string &name)
Find the full path to a file.
A single value (typically within a Bottle).
Definition Value.h:44
virtual std::string asString() const
Get string value.
Definition Value.cpp:246
bool speedview_param_enabled
Definition main.cpp:35
bool debug_param_enabled
Definition main.cpp:34
bool enable_calib_all
Definition main.cpp:36
Definition aboutdlg.h:11
#define MAX_WIDTH_JOINT
Definition partitem.h:37