Unity-Technologies / ROS-TCP-Endpoint

ROS package used to create an endpoint to accept ROS messages sent from a Unity scene using the ROS TCP Connector scripts
Apache License 2.0
177 stars 118 forks source link

Potential memory leak when creating Unity subscriber #144

Open mqt0029 opened 2 years ago

mqt0029 commented 2 years ago

Describe the bug When registering subscriber from Unity to a ROS message e.g.

ROS.Subscribe<ImageMsg>("/hmd/rgb/image_raw", HandleGazeboCameraMsg);

memory usage of default_server_endpoint.py rises rapidly and will not release until ROS is shutdown via CTRL-C.

To Reproduce Steps to reproduce the behavior:

  1. Launch the default_server_endpoint.py via roslaunch i.e roslaunch ros_tcp_endpoint endpoint.launch along with other topics you want Unity to be able to access, my case were images from a Gazebo simulated camera.
  2. Start a ROS connection in Unity via a script and register a subscriber i.e.
    
    // [Relevant using statements]

public class ROSManager : MonoBehaviour { public ROSConnection ROS; public Camera HeadMountDisplay;

// Start is called before the first frame update
void Start()
{
    // connect to ROS, works
    ROS = ROSConnection.GetOrCreateInstance();

    // publish to ROS, works
    ROS.RegisterPublisher<PoseMsg>("/unity/hmd_pose");    

    // shortly after subscribing, RAM goes skyhigh and never came back down...
    ROS.Subscribe<ImageMsg>("/hmd/rgb/image_raw", HandleGazeboCameraMsg); 
}

// Update is called once per frame
void Update()
{
    // works as expected
    var hmd_pose = new PoseMsg();
    hmd_pose.position = HeadMountDisplay.transform.position.To<FLU>();
    hmd_pose.orientation = HeadMountDisplay.transform.rotation.To<FLU>();
    ROS.Publish("/unity/hmd_pose", hmd_pose);
}

void HandleGazeboCameraMsg(ImageMsg img_msg)
{
    // does not matter if there is something running here
}

}


3. See RAM goes up rapidly, does not get clean up.

**Console logs / stack traces**
Unity console log did not report anything. I have attached ROS logs as additional information.
[ROS-log-ff137296-c503-11ec-bb7b-e4b97af38577.zip](https://github.com/Unity-Technologies/ROS-TCP-Endpoint/files/8559251/ROS-log-ff137296-c503-11ec-bb7b-e4b97af38577.zip)

**Expected behavior**
RAM usage should go up since there is active communication between the two, assuming message encoding/decoding matters, but not at that rate.

**Screenshots**
![Peek 2022-04-25 20-56](https://user-images.githubusercontent.com/46615495/165205246-c7f01ba0-24ed-4d22-a0b0-0a1b8176e6d8.gif)

**Environment (please complete the following information, where applicable):**
Original issue first noticed while using Docker on WSL on Windows 11. I  assumed it has something to do with WSL so I ported my code to a different machine running Ubuntu 20.04, same result.

- Unity Version: 2020.3.33f1 and 2021.3.1f1
- Unity machine OS + version: Windows 11 10.0.22000 Build 22000
- ROS machine OS + version: 
  - Windows 11 10.0.22000 Build 22000
  - Ubuntu 20.04 kernel 5.13.0-40-generic
- ROS–Unity communication: 
  - ROS on Ubuntu 20.04 Docker on WSL, Docker IP connection
  - ROS directly on WSL, localhost connection
  - ROS on Ubuntu 20.04 Docker on Ubuntu 20.04 across LAN, Unity remains on Windows machine
  - ROS directly on Ubuntu 20.04 across LAN, Unity remains on Windows machine
- Branch or version: tried 0.7.0 and 0.6.0, did not go back further since the syntax seems to have been updated.

**Additional context**
As long as there is nothing published on the topic, this issue doesn't happen i.e. subscribing to an empty `/joint_states` topic does not increase RAM usage. ~~I remember distinctively having to declare publisher/subscriber way back when but can't seem to find the reference, I'll add once I found it.~~ Found the old example in [Unity-Robotics-Hub v0.5.0](https://github.com/Unity-Technologies/Unity-Robotics-Hub/blob/513c4543feca9b9acf1e6d56a06c8a9cb86e77d0/tutorials/pick_and_place/ROS/src/niryo_moveit/scripts/server_endpoint.py). It seems the newer syntax has made this obsolete.

It might be related to #139, #124, and #19. As far as I can tell there is no noticable differences between swapping out any version of either [ROS-TCP-Endpoint](https://github.com/Unity-Technologies/ROS-TCP-Endpoint) or [ROS-TCP-Connector](https://github.com/Unity-Technologies/ROS-TCP-Connector).
LaurieCheers-unity commented 2 years ago

Hi, sorry for the delay in responding to this issue. I ran your sample code (after modifying it to actually publish an image) but I haven't been able to reproduce the memory leak. Which is very mysterious, since you seem to have reproduced it in many separate environments. Could you share a more complete sample?

Also, to unblock you for now, I suggest you try the Roscpp branch of ROS-TCP-Endpoint. This is a rewrite of the endpoint in C++, and should have lower CPU and memory consumption. It's currently in beta, not fully tested but bug reports are welcome.

mqt0029 commented 2 years ago

It will take some time to port out a section of code that I can publish here since it is behind a private research project. Furthermore, may I inquire how you plan to running the sample? I asked because my current setup requires a number of setup steps to generate my current setup on Windows and/or Ubuntu OS. Docker can be extremely helpful in normalizing the development environment here.

In the meantime, can you clarify what you meant by "modifying it to publish an image"? The problem occurs when Unity subscribe to a ROS topic that is publishing a sensor_msgs/Image.msg message, not publishing images from Unity. I believe there is some confusion here. If possible, please also provide your code sample here.

Cranc commented 2 years ago

Hello, I can confirm this issue. In fact, I ran into the exact same issue yesterday on an Ubuntu 20.04 environment while trying to send image data from gazebo -> Ros TCP-Endpoint -> Unity. Moreover, it does happen only once the unity applications subscribes to the topic and not prior.

I Tested this running the TCP-Endpoint and the application on the same machine, as well as running the application on a Occulus VR-Headset and the TCP-Endpoint on the aformentioned Ubuntu enviroment.

Given how fast the memory leak occurs for me once connected (about 32GB in less than 3min) I assume at this point it has something to do with the data field in ImageMsg not being released correctly on the server. (Im sending about 60-70 fps in 720p)