Custom QT GUI in ROS for real time data freeze
Hi,
I am new to integrating ROS with QT. I am developing a custom gui to publish topic directly to a GUI that displays data in real time as it is read from a unit.
I followed this link: http://wiki.ros.org/qt_create/Tutoria... .
GUI seems to work except it freezes after couple of minutes. Below is concept of how I have implemented.
---include/
- main_winndow.hpp
-qnode.hpp`
---src/
-main.cpp
-main_winndow.cpp => updates UI
-qnode.cpp => starts ros, reads ethernet packets from unit and publishes as "/raw_packets". Rawpacket is remapped to "input_data" in launch file and subscribed to functions call "msgrec" that decodes packets to topic parameters. I have 2 Q_EMIT. one to update ROS info in LIST-VIEW of UI and second Q_EMIT is after decoding of packets.
main_winndow.cpp
:
:
MainWindow::MainWindow(int argc, char** argv, QWidget *parent)
: QMainWindow(parent)
, qnode(argc,argv)
{
:
:
// CONNECT GUI Button to Qnode init
QObject::connect(ui.BUTTON, SIGNAL(clicked()), this, SLOT(StartqnodeInit()));
// SIGNAL from Qnode after messages are read from unit to be displayed on GUI
QObject::connect(&qnode,
SIGNAL(logunitsmessages(std::string, std::string)), this,
SLOT(ui_logunitsmessages(std::string, std::string)));
// GUI List view gets updated after loggingUpdated signal from qnode
ui.listView_log->setModel(qnode.loggingModel());
QObject::connect(&qnode, SIGNAL(loggingUpdated()), this, SLOT(updateLoggingView()));
}
void MainWindow::StartqnodeInit()
{
if ( !qnode.init(ui.lineEdit->text().toStdString()) ) {
showNoMasterMessage();
}
}
/*****************************************************************************
** GUI UPDATE HERE
*****************************************************************************/
void MainWindow::updateLoggingView() // LIST View updated here in signal loggingUpdated() from QNode
{
ui.listView_log->scrollToBottom();
}
void MainWindow::ui_logunitsmessages( std::string msg1, std::string msg2 )
{
// LABELS updated here in signal logunitsmessages() from QNode
ui.msg1_valuelabel->setText(QString::fromStdString(msg1));
ui.msg2_valuelabel->setText(QString::fromStdString(msg2));
}
}
qnode.cpp
:
:
// INIT
bool QNode::init() {
ros::init(init_argc,init_argv,"qexample");
if ( ! ros::master::check() ) {
return false;
}
ros::start(); // explicitly needed since our nodehandle is going out of scope.
ros::NodeHandle n;
pub_rawpack_ = n.advertise<custometh::ethpacket>("/raw_packets", 1, this);
sub_rawpack_ = n.subscribe(input_data, 1, &QNode::msgrec, this);
pub_topicmsg_ = n.advertise<std_msgs::String>("/decodedmsg", 1);
start();
return true;
}
// RUN
void QNode::run() {
ros::Rate loop_rate(10);
/* loop until shut down or end of file */
while(ros::ok() && rawpacketpolling())
{
pub_topicmsg_.publish(topicmessage);
Q_EMIT logunitsmessages(topicmessage.msg1, topicmessage.msg2); // EMIT after messages is decoded.
ros::spinOnce();
loop_rate.sleep();
}
Q_EMIT rosShutdown(); // used to signal the gui for a shutdown (useful to roslaunch)
}
msgrec ()
{
//code that decodes raw packets into "topicmessage" msg of std_msgs::String type
}
void QNode::log( const LogLevel &level, const std::string &msg) {
: // some code here
Q_EMIT loggingUpdated(); // used to readjust the scrollbar
}
I have read couple of posts that say to use QTime. Could someone help me how I can use Qtime in my example. If Qtime is not the right way to defreeze then what is the right method to go about to display real time topic without GUI freeze.