Why UE4 becomes stuttered after play if the rosbridge_server in another machine doesn't open?
In my case, I run UE4(with ROSIntegration) in win10 but I didn't start the rosbridge_server(rosbridge_tcp) in another pc. However. After I clicked the "Play" button, the UE4 world became stuttered. This will also happen if I terminate the rosbridge_server on purpose.
I found this caused by "if (!_sock->Connect(*addr))" in "bool TCPConnection::Init(std::string ip_addr, int port)" which consumes at least 2 seconds in my system。"void UROSIntegrationGameInstance::Init()" will be called in "UROSIntegrationGameInstance::CheckROSBridgeHealth" periodically while rosbridge_server not started. I tried to fix this but still encountered some problems.
Problem solved! The root cause is ”_sock->Connect(*addr)“ works in blocking mode, blocking time will be affected by system implementation which is unpredictable. So it's necessary to set non-block mode first.
I tried to fix like this:
-
TCPConnection.cpp bool TCPConnection::Init(std::string ip_addr, int port) { ... #if 0 if (!_sock->Connect(*addr)) #else
bool bConnected = false; _sock->SetNonBlocking(true); bConnected = _sock->Connect(*addr); _sock->SetNonBlocking(false); // If using _sock->Wait also blocks if (bConnected ) //&& _sock->Wait(ESocketWaitConditions::WaitForWrite, FTimespan::FromSeconds(2))) { // do nothing } else #endif { return false; } ... }
-
In ROSIntegrationGameInstance.cpp
void UROSIntegrationGameInstance::Init() { #if 0 if (!bTimerSet) { bTimerSet = true; GetTimerManager().SetTimer(TimerHandle_CheckHealth, this, &UROSIntegrationGameInstance::CheckROSBridgeHealth, 1.0f, true, 5.0f); } #else if (!bTimerSet) { bTimerSet = true; GetTimerManager().SetTimer(TimerHandle_CheckHealth, this, &UROSIntegrationGameInstance::CheckROSBridgeHealth, 5.0f, true, 5.0f); } #endif }
This is not the optimal solution but combined these two changes does help to my case.