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 *enableControlMixed =
windows->addAction(
"Enable Mixed Control");
254 QAction *enableControlPositionDirect =
windows->addAction(
"Enable Position Direct Control");
255 QAction *enableControlPWM =
windows->addAction(
"Enable PWM Control");
256 QAction *enableControlCurrent =
windows->addAction(
"Enable Current Control");
265 enableControlVelocity->setCheckable(
true);
266 enableControlMixed->setCheckable(
true);
267 enableControlPositionDirect->setCheckable(
true);
268 enableControlPWM->setCheckable(
true);
269 enableControlCurrent->setCheckable(
true);
270 viewPositionTargetBox->setCheckable(
true);
271 viewPositionTargetValue->setCheckable(
true);
273 QSettings settings(
"YARP",
"yarpmotorgui");
276 bool bSpeedValues = settings.value(
"SpeedValuesVisible",
false).toBool();
280 bool bviewDutyCycles = settings.value(
"DutyCycleVisible",
false).toBool();
281 bool bCurrentValues = settings.value(
"CurrentsVisible",
false).toBool();
291 enableControlVelocity->setChecked(
false);
292 enableControlMixed->setChecked(
false);
293 enableControlPositionDirect->setChecked(
false);
294 enableControlPWM->setChecked(
false);
295 enableControlCurrent->setChecked(
false);
306 connect(viewPositionTargetBox,
SIGNAL(
triggered(
bool)),
this,
SLOT(onViewPositionTargetBox(
bool)));
307 connect(viewPositionTargetValue,
SIGNAL(
triggered(
bool)),
this,
SLOT(onViewPositionTargetValue(
bool)));
308 connect(enableControlVelocity,
SIGNAL(
triggered(
bool)),
this,
SLOT(onEnableControlVelocity(
bool)));
309 connect(enableControlMixed,
SIGNAL(
triggered(
bool)),
this,
SLOT(onEnableControlMixed(
bool)));
310 connect(enableControlPositionDirect,
SIGNAL(
triggered(
bool)),
this,
SLOT(onEnableControlPositionDirect(
bool)));
312 connect(enableControlCurrent,
SIGNAL(
triggered(
bool)),
this,
SLOT(onEnableControlCurrent(
bool)));
315 connect(
this,
SIGNAL(sig_internalClose()),
this,
SLOT(close()),Qt::QueuedConnection);
320 lay->setSizeConstraint(QLayout::SetMaximumSize);
321 m_ui->treeWidgetContainer->setLayout(
lay);
323 connect(m_modesTreeManager,
SIGNAL(sig_jointClicked(
int,
int)),
this,
SLOT(onJointClicked(
int,
int)));
324 connect(m_modesTreeManager,
SIGNAL(sig_partDoubleClicked(
int)),
this,
SLOT(onPartDoubleClicked(
int)));
326 m_timer.setInterval(200);
327 m_timer.setSingleShot(
false);
328 connect(&m_timer,
SIGNAL(timeout()),
this,
SLOT(onUpdate()), Qt::QueuedConnection);
334 m_glowEffect->setOffset(.0);
336 m_glowEffect->setColor(Qt::yellow);
338 m_glowTimer.setSingleShot(
true);
339 connect(&m_glowTimer,
SIGNAL(timeout()),
this,
SLOT(onGlowTimerExpired()));
346 disconnect(&m_timer,
SIGNAL(timeout()),
this,
SLOT(onUpdate()));
353 for (
int i = 0; i<m_tabPanel->count(); i++)
355 if (m_tabPanel->widget(i))
357 delete m_tabPanel->widget(i);
361 m_tabPanel =
nullptr;
375void MainWindow::onSequenceActivated()
377 m_sequenceActiveCount++;
378 m_goAll->setEnabled(
false);
379 m_runAllSeq->setEnabled(
false);
380 m_runAllSeqTime->setEnabled(
false);
381 m_saveAllSeq->setEnabled(
false);
382 m_loadAllSeq->setEnabled(
false);
383 m_cycleAllSeq->setEnabled(
false);
384 m_cycleAllSeqTime->setEnabled(
false);
385 m_runAllParts->setEnabled(
false);
386 m_idleAllParts->setEnabled(
false);
387 m_homeAllParts->setEnabled(
false);
390void MainWindow::onSequenceStopped()
392 m_sequenceActiveCount--;
393 if (m_sequenceActiveCount <= 0)
395 m_sequenceActiveCount = 0;
396 m_goAll->setEnabled(
true);
397 m_runAllSeq->setEnabled(
true);
398 m_runAllSeqTime->setEnabled(
true);
399 m_saveAllSeq->setEnabled(
true);
400 m_loadAllSeq->setEnabled(
true);
401 m_cycleAllSeq->setEnabled(
true);
402 m_cycleAllSeqTime->setEnabled(
true);
403 m_runAllParts->setEnabled(
true);
404 m_idleAllParts->setEnabled(
true);
405 m_homeAllParts->setEnabled(
true);
410void MainWindow::onViewGlobalToolbar(
bool val)
412 QSettings settings(
"YARP",
"yarpmotorgui");
413 settings.setValue(
"GlobalToolVisible",val);
415 m_globalToolBar->hide();
417 m_globalToolBar->show();
422void MainWindow::onViewPartToolbar(
bool val)
424 QSettings settings(
"YARP",
"yarpmotorgui");
425 settings.setValue(
"PartToolVisible",val);
427 m_partToolBar->hide();
429 m_partToolBar->show();
433void MainWindow::onEnableControlVelocity(
bool val)
438void MainWindow::onEnableControlMixed(
bool val)
443void MainWindow::onEnableControlPositionDirect(
bool val)
448void MainWindow::onEnableControlPWM(
bool val)
453void MainWindow::onEnableControlCurrent(
bool val)
458void MainWindow::onSliderOptionsClicked()
465 m_sliderOpt =
nullptr;
468void MainWindow::onViewSpeeds(
bool val)
470 QSettings settings(
"YARP",
"yarpmotorgui");
471 settings.setValue(
"SpeedValuesVisible",val);
476void MainWindow::onViewCurrents(
bool val)
478 QSettings settings(
"YARP",
"yarpmotorgui");
479 settings.setValue(
"CurrentValuesVisible", val);
484void MainWindow::onViewMotorPositions(
bool val)
486 QSettings settings(
"YARP",
"yarpmotorgui");
487 settings.setValue(
"MotorPositionVisible", val);
492void MainWindow::onViewDutyCycles(
bool val)
494 QSettings settings(
"YARP",
"yarpmotorgui");
495 settings.setValue(
"DutyCyclesVisible", val);
500void MainWindow::onViewPositionTargetBox(
bool val)
502 QSettings settings(
"YARP",
"yarpmotorgui");
503 settings.setValue(
"ViewPositionTarget", val);
508void MainWindow::onViewPositionTargetValue(
bool val)
510 QSettings settings(
"YARP",
"yarpmotorgui");
511 settings.setValue(
"ViewPositionTarget", val);
516void MainWindow::onSetPosSliderOptionMW(
int choice,
double val,
int digits)
520void MainWindow::onSetVelSliderOptionMW(
int choice,
double val)
524void MainWindow::onSetTrqSliderOptionMW(
int choice,
double val)
529void MainWindow::onJointClicked(
int partIndex,
int jointIndex)
538 auto*
jointWidget = part->getJointWidget(jointIndex);
540 m_glowEffect->setEnabled(
false);
542 m_glowEffect->setEnabled(
true);
546void MainWindow::onGlowTimerExpired()
548 m_glowEffect->setEnabled(
false);
551void MainWindow::onPartDoubleClicked(
int partIndex)
567 disconnect(&m_timer,
SIGNAL(timeout()),
this,
SLOT(onUpdate()));
574 for (
int i = 0; i<m_tabPanel->count(); i++){
575 if (m_tabPanel->widget(i)){
576 delete m_tabPanel->widget(i);
580 m_tabPanel =
nullptr;
585 QMainWindow::closeEvent(event);
598 m_tabPanel =
new QTabWidget(m_ui->mainContainer);
602 m_calibSinglePart->setEnabled(
false);
626 std::map<std::string, robot_type>
robots;
627 std::map<std::string, part_type>
parts;
632 size_t b1 =
ss.find(
'/');
633 size_t b2 =
ss.find(
'/',
b1 + 1);
634 if (
b1 == std::string::npos ||
635 b2 == std::string::npos)
637 yError() <<
"Invalid parts name, missing / char?";
646 if (r.robot_name_without_slash[0] ==
'/') {
647 r.robot_name_without_slash.erase(0, 1);
654 p.part_name_without_slash =
ss.substr(
b2);
655 if (p.part_name_without_slash[0] ==
'/') {
656 p.part_name_without_slash.erase(0, 1);
663 for (
auto& robot :
robots)
665 m_modesTreeManager->
addRobot(robot.first.c_str());
673 scroll->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
674 scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
675 scroll->setWidgetResizable(
true);
685 connect(part,
SIGNAL(sequenceActivated()),
this,
SLOT(onSequenceActivated()));
686 connect(part,
SIGNAL(sequenceStopped()),
this,
SLOT(onSequenceStopped()));
708 m_currentPartMenu->setTitle(
QString(
"%1 Commands ").arg(
auxName));
730 if((
unsigned int)errorCount ==
parts.size())
738 m_ui->mainContainer->setLayout(
lay);
739 m_ui->mainContainer->layout()->addWidget(m_tabPanel);
742 QSettings settings(
"YARP",
"yarpmotorgui");
743 bool speedVisible = settings.value(
"SpeedValuesVisible",
false).toBool();
744 bool motorPosVisible = settings.value(
"MotorPositionVisible",
false).toBool();
745 bool currentVisible = settings.value(
"CurrentsVisible",
false).toBool();
746 bool dutyVisible = settings.value(
"DutyCyclesVisible",
false).toBool();
756void MainWindow::onCurrentPartChanged(
int index)
761 QString partName = m_tabPanel->tabText(index);
764 auxName.replace(0,1,partName.at(0).toUpper());
774 part->resizeWidget(part->width());
778void MainWindow::onCalibSinglePart()
790 if (QMessageBox::question(
this,
"Question",
QString(
"Do you really want to recalibrate all joints of this part?")) == QMessageBox::Yes)
792 part->calibratePart();
796void MainWindow::onExecuteScript1()
798 if (m_user_script1 ==
"")
800 QMessageBox::information(
this,
"Info",
QString(
"user script1 not specified. use --script1 option"));
804 if (QMessageBox::question(
this,
"Question",
QString(
"Do you really want to execute user script1?")) == QMessageBox::Yes)
812 yDebug() <<
"yarpmotorgui_script1 returned value:" << r;
816 QMessageBox::information(
this,
"Info",
QString(
"Unable to find script1 file"));
821 QMessageBox::information(
this,
"Info",
QString(
"System is unable to run script1"));
826void MainWindow::onExecuteScript2()
828 if (m_user_script2 ==
"")
830 QMessageBox::information(
this,
"Info",
QString(
"user script2 not specified. use --script2 option"));
834 if (QMessageBox::question(
this,
"Question",
QString(
"Do you really want to execute user script2?")) == QMessageBox::Yes)
842 yDebug() <<
"yarpmotorgui_script2 returned value:" << r;
846 QMessageBox::information(
this,
"Info",
QString(
"Unable to find script2 file"));
851 QMessageBox::information(
this,
"Info",
QString(
"System is unable to run script2"));
856void MainWindow::onHomeSinglePart()
858 if (QMessageBox::question(
this,
"Question",
"Do you really want to home all joints of this part?") != QMessageBox::Yes){
875void MainWindow::onHomeAllParts()
877 if (QMessageBox::question(
this,
"Question",
"Do you really want to home all parts?") != QMessageBox::Yes){
885 for (
int i = 0; i<m_tabPanel->count(); i++)
900 if (QMessageBox::question(
this,
"Question",
"Do you really want to home all parts?") != QMessageBox::Yes){
908 for (
int i = 0; i<m_tabPanel->count(); i++)
924 if (QMessageBox::question(
this,
"Question",
"Do you really want to home all joints of this part?") != QMessageBox::Yes){
941void MainWindow::onIdleSinglePart()
956void MainWindow::onCycleTimeAllSeq()
964 for (
int i = 0; i<m_tabPanel->count(); i++){
971 bool done = part->checkAndCycleTimeAllSeq();
977 QMessageBox::critical(
this,
"Error",
QString(
"Load a valid sequence before performing this action for these parts:\n%1").arg(
notSelectedParts));
981void MainWindow::onCycleAllSeq()
989 for (
int i = 0; i<m_tabPanel->count(); i++){
996 bool done = part->checkAndCycleAllSeq();
1002 QMessageBox::critical(
this,
"Error",
QString(
"Load a valid sequence before performing this action for these parts:\n%1").arg(
notSelectedParts));
1006void MainWindow::onRunAllSeq()
1014 for (
int i = 0; i<m_tabPanel->count(); i++){
1021 bool done = part->checkAndRunAllSeq();
1027 QMessageBox::critical(
this,
"Error",
QString(
"Load a valid sequence before performing this action for these parts:\n%1").arg(
notSelectedParts));
1032void MainWindow::onRunTimeAllSeq()
1040 for (
int i = 0; i<m_tabPanel->count(); i++){
1047 bool done = part->checkAndRunTimeAllSeq();
1053 QMessageBox::critical(
this,
"Error",
QString(
"Load a valid sequence before performing this action for these parts:\n%1").arg(
notSelectedParts));
1057void MainWindow::onLoadAllSeq()
1064 for (
int i = 0; i<m_tabPanel->count(); i++){
1071 part->loadSequence();
1076void MainWindow::onSaveAllSeq()
1082 QString fileName = QFileDialog::getSaveFileName(
this,
QString(
"Save Sequence for all parts as:"), QDir::homePath());
1084 for (
int i = 0; i<m_tabPanel->count(); i++)
1092 part->saveSequence(fileName);
1093 part->closeSequenceWindow();
1097void MainWindow::onStopAllSeq()
1104 for (
int i = 0; i<m_tabPanel->count(); i++){
1111 part->stopSequence();
1117void MainWindow::onGoAll()
1125 for (
int i = 0; i<m_tabPanel->count(); i++){
1132 bool done = part->checkAndGo();
1139 QMessageBox::critical(
this,
"Error",
QString(
"Select a valid entry in the table before performing a movement for these parts:\n%1").arg(
notSelectedParts));
1144void MainWindow::onIdleAllParts()
1146 if (QMessageBox::question(
this,
"Question",
"Do you really want to idle all parts?") != QMessageBox::Yes){
1154 for (
int i = 0; i<m_tabPanel->count(); i++)
1166void MainWindow::onRunAllParts()
1172 for (
int i = 0; i<m_tabPanel->count(); i++){
1183void MainWindow::onRunSinglePart()
1198void MainWindow::onOpenSequenceTab()
1209 part->openSequenceWindow();
1214void MainWindow::onUpdate()
1231 for (
int i = 0; i<m_tabPanel->count(); i++)
1235 item->updateControlMode();
1239 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_setPosSliderOptionMW(int, double, int)
void sig_setVelSliderOptionMW(int, double)
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_setTrqSliderOptionMW(int, double)
void sig_viewMotorPositions(bool)
void sig_viewDutyCycles(bool)
void sig_enableControlCurrent(bool)
void sig_viewCurrentValues(bool)
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