8#include "ui_mainwindow.h"
19#include <QFontMetrics>
35 QLocale::setDefault(QLocale::C);
37 m_sequenceActiveCount = 0;
39 setWindowTitle(
"Qt Robot Motor GUI V2.0");
42 m_sliderOpt =
nullptr;
45 m_globalToolBar =
new QToolBar(
"Global Joints Commands",
this);
51 m_globalToolBar->addWidget(
label1)->setCheckable(
false);
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);
95 for (
size_t index = 0; index <
ini.size(); ++index) {
109 std::string key =
subElement->get(0).asString();
110 std::string
pattern =
"customPosition_";
129 m_customPositionsAllParts.push_back(
newAction);
137 newAction->setShortcutContext(Qt::ApplicationShortcut);
168 m_partToolBar =
new QToolBar(
"Current Part",
this);
169 m_partToolBar->setMovable(
true);
170 m_partToolBar->setFloatable(
true);
171 m_partToolBar->setAllowedAreas(Qt::AllToolBarAreas);
173 m_partName =
new QLabel(
"NONE");
174 f = m_partName->font();
176 m_partName->setFont(
f);
178 m_partToolBar->addWidget(m_partName)->setCheckable(
false);
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");
192 m_customPositionsSinglePartToolbar.push_back(
newAction);
201 addToolBar(m_partToolBar);
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);
220 m_customPositionsSinglePartToolbar.push_back(
newAction);
228 newAction->setShortcutContext(Qt::ApplicationShortcut);
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");
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);
277 QSettings settings(
"YARP",
"yarpmotorgui");
280 bool bSpeedValues = settings.value(
"SpeedValuesVisible",
false).toBool();
284 bool bviewDutyCycles = settings.value(
"DutyCycleVisible",
false).toBool();
285 bool bCurrentValues = settings.value(
"CurrentsVisible",
false).toBool();
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);
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)));
319 connect(enableControlCurrent,
SIGNAL(
triggered(
bool)),
this,
SLOT(onEnableControlCurrent(
bool)));
320 connect(enableControlTorque,
SIGNAL(
triggered(
bool)),
this,
SLOT(onEnableControlTorque(
bool)));
323 connect(
this,
SIGNAL(sig_internalClose()),
this,
SLOT(close()),Qt::QueuedConnection);
328 lay->setSizeConstraint(QLayout::SetMaximumSize);
329 m_ui->treeWidgetContainer->setLayout(
lay);
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)));
334 m_timer.setInterval(200);
335 m_timer.setSingleShot(
false);
336 connect(&m_timer,
SIGNAL(timeout()),
this,
SLOT(onUpdate()), Qt::QueuedConnection);
342 m_glowEffect->setOffset(.0);
344 m_glowEffect->setColor(Qt::yellow);
346 m_glowTimer.setSingleShot(
true);
347 connect(&m_glowTimer,
SIGNAL(timeout()),
this,
SLOT(onGlowTimerExpired()));
354 disconnect(&m_timer,
SIGNAL(timeout()),
this,
SLOT(onUpdate()));
361 for (
int i = 0; i<m_tabPanel->count(); i++)
363 if (m_tabPanel->widget(i))
365 delete m_tabPanel->widget(i);
369 m_tabPanel =
nullptr;
383void MainWindow::onSequenceActivated()
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);
398void MainWindow::onSequenceStopped()
400 m_sequenceActiveCount--;
401 if (m_sequenceActiveCount <= 0)
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);
418void MainWindow::onViewGlobalToolbar(
bool val)
420 QSettings settings(
"YARP",
"yarpmotorgui");
421 settings.setValue(
"GlobalToolVisible",val);
423 m_globalToolBar->hide();
425 m_globalToolBar->show();
430void MainWindow::onViewPartToolbar(
bool val)
432 QSettings settings(
"YARP",
"yarpmotorgui");
433 settings.setValue(
"PartToolVisible",val);
435 m_partToolBar->hide();
437 m_partToolBar->show();
441void MainWindow::onEnableControlVelocity(
bool val)
446void MainWindow::onEnableControlVelocityDirect(
bool val)
451void MainWindow::onEnableControlMixed(
bool val)
456void MainWindow::onEnableControlPositionDirect(
bool val)
461void MainWindow::onEnableControlPWM(
bool val)
466void MainWindow::onEnableControlCurrent(
bool val)
471void MainWindow::onEnableControlTorque(
bool val)
476void MainWindow::onSliderOptionsClicked()
483 m_sliderOpt =
nullptr;
486void MainWindow::onViewSpeeds(
bool val)
488 QSettings settings(
"YARP",
"yarpmotorgui");
489 settings.setValue(
"SpeedValuesVisible",val);
494void MainWindow::onViewCurrents(
bool val)
496 QSettings settings(
"YARP",
"yarpmotorgui");
497 settings.setValue(
"CurrentValuesVisible", val);
502void MainWindow::onViewMotorPositions(
bool val)
504 QSettings settings(
"YARP",
"yarpmotorgui");
505 settings.setValue(
"MotorPositionVisible", val);
510void MainWindow::onViewDutyCycles(
bool val)
512 QSettings settings(
"YARP",
"yarpmotorgui");
513 settings.setValue(
"DutyCyclesVisible", val);
518void MainWindow::onViewPositionTargetBox(
bool val)
520 QSettings settings(
"YARP",
"yarpmotorgui");
521 settings.setValue(
"ViewPositionTarget", val);
526void MainWindow::onViewPositionTargetValue(
bool val)
528 QSettings settings(
"YARP",
"yarpmotorgui");
529 settings.setValue(
"ViewPositionTarget", val);
534void MainWindow::onSetPosSliderOptionMW(
int choice,
double val,
int digits)
538void MainWindow::onSetVelSliderOptionMW(
int choice,
double val,
int digits)
542void MainWindow::onSetAccSliderOptionMW(
int choice,
double val,
int digits)
546void MainWindow::onSetTrqSliderOptionMW(
int choice,
double val,
int digits)
550void MainWindow::onSetCurSliderOptionMW(
int choice,
double val,
int digits)
555void MainWindow::onJointClicked(
int partIndex,
int jointIndex)
564 auto*
jointWidget = part->getJointWidget(jointIndex);
566 m_glowEffect->setEnabled(
false);
568 m_glowEffect->setEnabled(
true);
572void MainWindow::onGlowTimerExpired()
574 m_glowEffect->setEnabled(
false);
577void MainWindow::onPartDoubleClicked(
int partIndex)
593 disconnect(&m_timer,
SIGNAL(timeout()),
this,
SLOT(onUpdate()));
600 for (
int i = 0; i<m_tabPanel->count(); i++){
601 if (m_tabPanel->widget(i)){
602 delete m_tabPanel->widget(i);
606 m_tabPanel =
nullptr;
611 QMainWindow::closeEvent(event);
625 m_tabPanel =
new QTabWidget(m_ui->mainContainer);
629 m_calibSinglePart->setEnabled(
false);
653 std::map<std::string, robot_type>
robots;
654 std::map<std::string, part_type>
parts;
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)
664 yError() <<
"Invalid parts name, missing / char?";
673 if (r.robot_name_without_slash[0] ==
'/') {
674 r.robot_name_without_slash.erase(0, 1);
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);
690 for (
auto& robot :
robots)
692 m_modesTreeManager->
addRobot(robot.first.c_str());
700 scroll->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
701 scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
702 scroll->setWidgetResizable(
true);
712 connect(part,
SIGNAL(sequenceActivated()),
this,
SLOT(onSequenceActivated()));
713 connect(part,
SIGNAL(sequenceStopped()),
this,
SLOT(onSequenceStopped()));
739 m_currentPartMenu->setTitle(
QString(
"%1 Commands ").arg(
auxName));
761 if((
unsigned int)errorCount ==
parts.size())
769 m_ui->mainContainer->setLayout(
lay);
770 m_ui->mainContainer->layout()->addWidget(m_tabPanel);
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();
787void MainWindow::onCurrentPartChanged(
int index)
792 QString partName = m_tabPanel->tabText(index);
795 auxName.replace(0,1,partName.at(0).toUpper());
805 part->resizeWidget(part->width());
809void MainWindow::onCalibSinglePart()
821 if (QMessageBox::question(
this,
"Question",
QString(
"Do you really want to recalibrate all joints of this part?")) == QMessageBox::Yes)
823 part->calibratePart();
827void MainWindow::onExecuteScript1()
829 if (m_user_script1 ==
"")
831 QMessageBox::information(
this,
"Info",
QString(
"user script1 not specified. use --script1 option"));
835 if (QMessageBox::question(
this,
"Question",
QString(
"Do you really want to execute user script1?")) == QMessageBox::Yes)
843 yDebug() <<
"yarpmotorgui_script1 returned value:" << r;
847 QMessageBox::information(
this,
"Info",
QString(
"Unable to find script1 file"));
852 QMessageBox::information(
this,
"Info",
QString(
"System is unable to run script1"));
857void MainWindow::onExecuteScript2()
859 if (m_user_script2 ==
"")
861 QMessageBox::information(
this,
"Info",
QString(
"user script2 not specified. use --script2 option"));
865 if (QMessageBox::question(
this,
"Question",
QString(
"Do you really want to execute user script2?")) == QMessageBox::Yes)
873 yDebug() <<
"yarpmotorgui_script2 returned value:" << r;
877 QMessageBox::information(
this,
"Info",
QString(
"Unable to find script2 file"));
882 QMessageBox::information(
this,
"Info",
QString(
"System is unable to run script2"));
887void MainWindow::onHomeSinglePart()
889 if (QMessageBox::question(
this,
"Question",
"Do you really want to home all joints of this part?") != QMessageBox::Yes){
906void MainWindow::onHomeAllParts()
908 if (QMessageBox::question(
this,
"Question",
"Do you really want to home all parts?") != QMessageBox::Yes){
916 for (
int i = 0; i<m_tabPanel->count(); i++)
931 if (QMessageBox::question(
this,
"Question",
"Do you really want to home all parts?") != QMessageBox::Yes){
939 for (
int i = 0; i<m_tabPanel->count(); i++)
955 if (QMessageBox::question(
this,
"Question",
"Do you really want to home all joints of this part?") != QMessageBox::Yes){
972void MainWindow::onIdleSinglePart()
987void MainWindow::onCycleTimeAllSeq()
995 for (
int i = 0; i<m_tabPanel->count(); i++){
1002 bool done = part->checkAndCycleTimeAllSeq();
1009 QMessageBox::critical(
this,
"Error",
QString(
"Load a valid sequence before performing this action for these parts:\n%1").arg(
notSelectedParts));
1013void MainWindow::onCycleAllSeq()
1021 for (
int i = 0; i<m_tabPanel->count(); i++){
1028 bool done = part->checkAndCycleAllSeq();
1034 QMessageBox::critical(
this,
"Error",
QString(
"Load a valid sequence before performing this action for these parts:\n%1").arg(
notSelectedParts));
1038void MainWindow::onRunAllSeq()
1046 for (
int i = 0; i<m_tabPanel->count(); i++){
1053 bool done = part->checkAndRunAllSeq();
1060 QMessageBox::critical(
this,
"Error",
QString(
"Load a valid sequence before performing this action for these parts:\n%1").arg(
notSelectedParts));
1065void MainWindow::onRunTimeAllSeq()
1073 for (
int i = 0; i<m_tabPanel->count(); i++){
1080 bool done = part->checkAndRunTimeAllSeq();
1087 QMessageBox::critical(
this,
"Error",
QString(
"Load a valid sequence before performing this action for these parts:\n%1").arg(
notSelectedParts));
1091void MainWindow::onLoadAllSeq()
1098 for (
int i = 0; i<m_tabPanel->count(); i++){
1105 part->loadSequence();
1110void MainWindow::onSaveAllSeq()
1116 QString fileName = QFileDialog::getSaveFileName(
this,
QString(
"Save Sequence for all parts as:"), QDir::homePath());
1118 for (
int i = 0; i<m_tabPanel->count(); i++)
1126 part->saveSequence(fileName);
1127 part->closeSequenceWindow();
1131void MainWindow::onStopAllSeq()
1138 for (
int i = 0; i<m_tabPanel->count(); i++){
1145 part->stopSequence();
1151void MainWindow::onGoAll()
1159 for (
int i = 0; i<m_tabPanel->count(); i++){
1166 bool done = part->checkAndGo();
1174 QMessageBox::critical(
this,
"Error",
QString(
"Select a valid entry in the table before performing a movement for these parts:\n%1").arg(
notSelectedParts));
1179void MainWindow::onIdleAllParts()
1181 if (QMessageBox::question(
this,
"Question",
"Do you really want to idle all parts?") != QMessageBox::Yes){
1189 for (
int i = 0; i<m_tabPanel->count(); i++)
1201void MainWindow::onRunAllParts()
1207 for (
int i = 0; i<m_tabPanel->count(); i++){
1218void MainWindow::onRunSinglePart()
1233void MainWindow::onOpenSequenceTab()
1244 part->openSequenceWindow();
1249void MainWindow::onUpdate()
1266 for (
int i = 0; i<m_tabPanel->count(); i++)
1270 item->updateControlMode();
1274 if (
item->updatePart() ==
false)
int SIGNAL(int pid, int signum)
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)
void sig_viewPositionTargetValue(bool)
void sig_viewSpeedValues(bool)
void sig_enableControlPositionDirect(bool)
void sig_viewMotorPositions(bool)
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)
A simple collection of objects that can be described and transmitted in a portable way.
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).
virtual std::string asString() const
Get string value.
bool speedview_param_enabled