Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve yarpmotorgui open speed #2911

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions doc/release/master/yarpmotorgui_open_speedup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
yarpmotorgui_open_speedup {#master}
---------------------------------



Branch: [S-Dafarra:yarpmotorgui_speedup](https://github.com/S-Dafarra/yarp/tree/yarpmotorgui_speedup)

#### `yarpmotorgui`

* Improved the initialization time of ``yarpmotorgui`` by:
* removing useless code
* using a dummy port to check conflicts with other ``yarpmotorgui`` instances
* parallelize the opening of the different robot part via ``std::async``

1 change: 1 addition & 0 deletions src/yarpmotorgui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ if(YARP_COMPILE_yarpmotorgui)
YARP::YARP_dev
Qt5::Widgets
Qt5::Gui
Threads::Threads
)

install(TARGETS yarpmotorgui COMPONENT utilities DESTINATION ${CMAKE_INSTALL_BINDIR})
Expand Down
74 changes: 56 additions & 18 deletions src/yarpmotorgui/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
#include <QSettings>
#include <QFileDialog>
#include <QShortcut>
#include <future>
#include <map>
#include <cstdlib>
#include <functional>
#include <yarp/os/LogStream.h>
#include <yarp/os/ResourceFinder.h>

Expand Down Expand Up @@ -603,8 +605,6 @@ bool MainWindow::init(QStringList enabledParts,
}

int errorCount = 0;
QScrollArea *scroll = nullptr;
PartItem *part = nullptr;
m_finder = finder;
m_user_script1 = m_finder.find("script1").asString();
m_user_script2 = m_finder.find("script2").asString();
Expand All @@ -623,6 +623,26 @@ bool MainWindow::init(QStringList enabledParts,
int partindex;
};

//checking existence of the port
int ind = 0;
QString portPrefix = QString("/yarpmotorgui%1").arg(ind);

// NameClient &nic=NameClient::getNameClient();
yDebug("Checking the existence of: %s \n", portPrefix.toLatin1().data());
Contact adr=Network::queryName(portPrefix.toLatin1().data());

while(adr.isValid()){
ind++;

portPrefix = QString("/yarpmotorgui%1").arg(ind);
yDebug("Checking the existence of: %s \n", portPrefix.toLatin1().data());
adr=Network::queryName(portPrefix.toLatin1().data());
}

m_testNamePort.open(portPrefix.toLatin1().data()); //This port is needed only to register a name in the nameserver,
//so that other instances of yarpmotorgui will use a different port name
m_testNamePort.setWriteOnly();

std::map<std::string, robot_type> robots;
std::map<std::string, part_type> parts;

Expand Down Expand Up @@ -659,23 +679,35 @@ bool MainWindow::init(QStringList enabledParts,
m_modesTreeManager->addRobot(robot.first.c_str());
}

std::vector<std::function<PartItem*()>> initLambdas;
std::vector<std::future<PartItem*>> partsFuture;

for (auto& i_parts : parts)
{
//JointItem *item = new JointItem();
//layout->addWidget(item);
scroll = new QScrollArea(m_tabPanel);
scroll->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
scroll->setWidgetResizable(true);
std::string part_name = i_parts.first;
std::string robot_name = i_parts.second.robot_name;
std::string robot_name_without_slash = i_parts.second.robot_name_without_slash;
std::string part_name_without_slash = i_parts.second.part_name_without_slash;
int part_id = i_parts.second.partindex;
part = new PartItem(robot_name_without_slash.c_str(), part_id, part_name_without_slash.c_str(), finder, debug_param_enabled, speedview_param_enabled, enable_calib_all, scroll);
PartItem* newPart = new PartItem(robot_name_without_slash.c_str(), portPrefix, part_id, part_name_without_slash.c_str(), debug_param_enabled, speedview_param_enabled, enable_calib_all);

initLambdas.push_back([newPart]() {
newPart->initializeYarpConnections();
return newPart;
});

//Run the yarp initialization of all the parts in parallell
partsFuture.emplace_back(std::async(std::launch::async, initLambdas.back()));
}

for (auto& partFuture : partsFuture)
{

PartItem *part = partFuture.get(); //Wait until the initialization of the corresponding part is over

if(part && !part->getInterfaceError())
{
part->initializeJointWidgets();
connect(part,SIGNAL(sequenceActivated()),this,SLOT(onSequenceActivated()));
connect(part,SIGNAL(sequenceStopped()),this,SLOT(onSequenceStopped()));
connect(this,SIGNAL(sig_viewSpeedValues(bool)),part,SLOT(onViewSpeedValues(bool)));
Expand All @@ -693,30 +725,36 @@ bool MainWindow::init(QStringList enabledParts,
connect(this, SIGNAL(sig_enableControlPWM(bool)), part, SLOT(onEnableControlPWM(bool)));
connect(this, SIGNAL(sig_enableControlCurrent(bool)), part, SLOT(onEnableControlCurrent(bool)));

QString part_name = "/" + part->getPartName();
QString robot_name = "/" + part->getRobotName();
int part_id = part->getPartIndex();
QScrollArea * scroll = new QScrollArea(m_tabPanel);
scroll->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
scroll->setWidgetResizable(true);
part->setParent(scroll);
scroll->setWidget(part);
int tabIndex = m_tabPanel->addTab(scroll, part_name.c_str());
int tabIndex = m_tabPanel->addTab(scroll, part_name);
if (part_id == 0)
{
QString auxName = part_name.c_str();
auxName.replace(0, 1, QString(part_name.c_str()).at(0).toUpper());
QString auxName = part_name;
auxName.replace(0, 1, QString(part_name).at(0).toUpper());
m_currentPartMenu->setTitle(QString("%1 Commands ").arg(auxName));
this->m_partName->setText(QString("%1 Commands ").arg(auxName));
}

m_modesTreeManager->addRobotPart(robot_name, part_name, tabIndex, part);
m_modesTreeManager->addRobotPart(robot_name.toStdString(), part_name.toStdString(), tabIndex, part);
}
else
{
if(part)
{
yError("Opening PolyDriver for part /%s failed...", part->getPartName().toLatin1().data());
QMessageBox::critical(nullptr, "Error opening a device", QString("Error while opening device for part /").append(part->getPartName()));

delete part;
part = nullptr;
}
if(scroll)
{
delete scroll;
scroll = nullptr;
}
errorCount++;
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/yarpmotorgui/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define MAINWINDOW_H

#include <yarp/os/ResourceFinder.h>
#include <yarp/os/Port.h>

#include <QMainWindow>
#include <QResizeEvent>
Expand Down Expand Up @@ -60,6 +61,7 @@ class MainWindow : public QMainWindow
ResourceFinder m_finder;
std::string m_user_script1;
std::string m_user_script2;
Port m_testNamePort;

QAction *m_goAll;
QAction *m_runAllSeq;
Expand Down
Loading