Closed julled closed 6 years ago
Hi, On the rosserial_server side everything seems ok, but it drops the connection after a 5sec timeout. It seems the node_handle timer on the client side isn't trigged (so spinOnce() isn't called in time) ; that could happen if the Qt event loop's thread is blocked (for example by a call to sleep() or another blocking method). Could you add some debug logs to int ros::NodeHandle::spinOnce() in node_handle.cpp and check it is called at least 10 times a second ?
it looks okey so far
timer elaped:108milliseks timer elaped:112milliseks timer elaped:109milliseks timer elaped:107milliseks timer elaped:112milliseks timer elaped:106milliseks timer elaped:109milliseks timer elaped:111milliseks timer elaped:109milliseks timer elaped:108milliseks timer elaped:110milliseks timer elaped:108milliseks timer elaped:112milliseks timer elaped:114milliseks timer elaped:102milliseks timer elaped:110milliseks timer elaped:112milliseks timer elaped:106milliseks timer elaped:109milliseks timer elaped:109milliseks timer elaped:110milliseks timer elaped:111milliseks timer elaped:109milliseks timer elaped:108milliseks timer elaped:113milliseks
measured with qelapsedtimer at the entry of spinOnce(). or does it need to be below 100ms?
Indeed the timer is called correctly (it just need to be below the timeout of the server) Could you maybe show your test code ?
As i want to send a gridmap, the functionnames are related to that... header
#include "ros/ros.h"
#include "ros/publisher.h"
#include <std_msgs/String.h>
class Rosconvertgrid{
private:
void callbackRaw();
ros::Publisher< std_msgs::String > chatter;
ros::NodeHandle nh;
bool m_ROSInit;
public:
Rosconvertgrid();
};
cpp
#include "pch.h"
#include "Rosconvertgrid.h"
Rosconvertgrid::Rosconvertgrid() :
chatter("chatter"),
m_ROSInit(false){}
void Rosconvertgrid::callbackRaw() {
if (!m_ROSInit)
{
std::string ros_master = "192.168.167.80";
nh.open(ros_master.c_str());
nh.advertise(chatter);
m_ROSInit = true;
}
static int i = 1;
i++;
std_msgs::String str_msg;
str_msg.data = QString("Hello %1").arg(i).toStdString();
chatter.publish(str_msg);
}
Rosconvertgrid::callbackRaw() gets called periodically (10 times a sec) by external function. If i look what happens on wireshark on the windows-pc(rosserial_qt), it looks like rosserial_qt doesnt send data, even there is a established tcp-connection. The 3 sek instead of 1 sek delay to disconnect (FIN-Pakets) is due i changed the attempt time in session.h ...
I tried your example and it is working fine on my computers (i have no disconnections and receive all the messages with rostopic echo /chatter
), I added the code below so you can try on your system.
Is your callback called from the same thread as Qt ? The publish() method is not thread-safe. (if it is not you could use QMetaObject::invokeMethod with a Qt::QueuedConnection)
Windows side :
#include <QCoreApplication>
#include <Qtimer>
#include "ros/ros.h"
#include "ros/publisher.h"
#include "std_msgs/String.h"
using std::string;
class Rosconvertgrid{
public:
Rosconvertgrid():
chatter("chatter"),
m_ROSInit(false){}
void callbackRaw(){
if (!m_ROSInit)
{
std::string ros_master = "192.168.0.56";
nh.open(ros_master.c_str());
nh.advertise(chatter);
m_ROSInit = true;
}
static int i = 1;
i++;
std_msgs::String str_msg;
str_msg.data = QString("Hello %1").arg(i).toStdString();
chatter.publish(str_msg);
}
private:
ros::Publisher< std_msgs::String > chatter;
ros::NodeHandle nh;
bool m_ROSInit;
};
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
Rosconvertgrid *rosconvertgrid = new Rosconvertgrid();
QTimer *timer = new QTimer();
timer->connect(
timer, &QTimer::timeout,
[rosconvertgrid]() { rosconvertgrid->callbackRaw(); }
);
timer->start(1000);
return app.exec();
}
Server launch :
<launch>
<node pkg="rosserial_server" type="socket_node" name="rosserial_server">
<param name="msg_length_bytes" value="4"/>
<param name="buffer_size" value="1000000"/>
<param name="tcp_nodelay" value="false"/>
</node>
<node pkg="rosserial_python" type="message_info_service.py" name="rosserial_message_info" />
</launch>
Thanks for the basic example. It looks like the tcp pakets gets blocked after sending via the qt tcpssocket. I am running out of ideas on what might be the problem, as i observed this problem with different errors on two different windows machines. I was switching over to a udpsocket and it worked like a charm. Maybe its better for my usecase as its faster anyway.
It turned out UDP wasnt a solution for us, as the message length of a UDP packet is 16 bit maximum. Thus we needed to get back to TCP, as it automatically splits the data in multiple packages. To get it working at our project, we needed to proceed as you proposed. We needed to connect node_handle with RosQTSocket by using the SignalSlot System to get it running. We emit a Signal with the constructed message in node_handle for a slot at the write function in RosQTSocket. Thank you for all your help!
Hey, thank you for your code ! I tried to make a simple test by sending a string message from a windows machine (like you do in your test code), but i am running into an issue at the rosserial-server side (https://github.com/1r0b1n0/rosserial/). I started the server on the linuxpc via the 32bit launchfile with 32bit msg-length and tcp_nodelay = false. The server seems to run out of sync with the client ("Sync with device lost."). Below are the first debug messages the server produces after connecting to the rosserial_qt client:
Do you have any idea how to resolve this issue?