RobotWebTools / ros3djs

3D Visualization Library for use with the ROS JavaScript Libraries
https://robotwebtools.github.io/ros3djs
Other
367 stars 216 forks source link

Memory growth due to MarkerArrayClient processMessage(arrayMessage) function #630

Open shyl886 opened 1 year ago

shyl886 commented 1 year ago

Description When I call ROS3D.MarkerArrayClient in my web, I see the web memory is increasing until crashing from Task Manager

Steps To Reproduce

function init() {
    // Create the main viewer.
    var viewer = new ROS3D.Viewer({
        divID: 'radar_markers',
        background: '#707070',
        width: 650,
        height: 650,
        antialias: true,
        displayPanAndZoomFrame: false
    });

    // Setup a client to listen to TFs.
    var tfClient = new ROSLIB.TFClient({
        ros: ros,
        angularThres: 0.01,
        transThres: 0.01,
        rate: 100.0,
        fixedFrame: '/rslidar'
    });

    var gridClient = new ROS3D.Grid({
        num_cells: 20
    });
    var axesClient = new ROS3D.Axes({
    });

    viewer.addObject(gridClient);
    viewer.addObject(axesClient);

    var markerArrayClient1 = new ROS3D.MarkerArrayClient({
        ros: ros,
        tfClient: tfClient,
        topic: '/vis_s1_objects',
        rootObject: viewer.scene
    });

    var markerArrayClient2 = new ROS3D.MarkerArrayClient({
        ros: ros,
        tfClient: tfClient,
        topic: '/vis_s2_objects',
        rootObject: viewer.scene
    });
    var markerArrayClient3 = new ROS3D.MarkerArrayClient({
        ros: ros,
        tfClient: tfClient,
        topic: '/vis_s3_objects',
        rootObject: viewer.scene
    });
}

Expected Behavior Open Chrome web, the memory is stable

Actual Behavior Memory is growing fast until crashing in several minutes

My Action In below ros3djs MarkerArrayClient class processMessage(arrayMessage) function, when I remove " this.rootObject.add(this.markers[key]); " , the web memory will become stable, so I guess maybe here will be the issue, does anybody know how to fix?

processMessage(arrayMessage) {
  arrayMessage.markers.forEach(function(message) {
      var key = message.ns + message.id;
      if (message.action === 0) {
          var updated = false;
          if (key in this.markers) { // "MODIFY"
              updated = this.markers[key].children[0].update(message);
              if (!updated) { // "REMOVE"
                  this.removeMarker(key);
              }
          }
          if (!updated) { // "ADD"
              var newMarker = new Marker({
                  message: message,
                  path: this.path,
              });
              this.markers[key] = new SceneNode({
                  frameID: message.header.frame_id,
                  tfClient: this.tfClient,
                  object: newMarker
              });
              this.rootObject.add(this.markers[key]);
          }
      } else if (message.action === 1) { // "DEPRECATED"
          console.warn('Received marker message with deprecated action identifier "1"');
      } else if (message.action === 2) { // "DELETE"
          this.removeMarker(key);
      } else if (message.action === 3) { // "DELETE ALL"
          for (var m in this.markers) {
              this.removeMarker(m);
          }
          this.markers = {};
      } else {
          console.warn('Received marker message with unknown action identifier "' + message.action + '"');
      }
  }.bind(this));
MatthijsBurgh commented 1 year ago

So I suggest you start with only one MarkerArrayClient and you track the keys you send. Because when you keep adding new stuff, of course the memory keeps growing. You can't visualize the entire world with only 100mb of memory usage...

shyl886 commented 1 year ago

@MatthijsBurgh I follow your suggestion and just leave one MarkerArrayClient, but the memory still keeps growing.

MatthijsBurgh commented 1 year ago

@shyl886 As I said, also track the keys, that are added. When you keep adding new keys and don't delete any. Of course the memory keeps growing...

shyl886 commented 1 year ago

@MatthijsBurgh I changed my Marker.id and Marker_text.id to a fixed value, but I see the memory is still rising, I attached my MarkerArray C++ program, could you help to have a look? Thank you very much.

void RADARRVIZ::s2_objects_callback(b7::TargetList s2_target_list){
    visualization_msgs::MarkerArray marker_array_points,marker_array_text;
    for(auto target : s2_target_list.targets){
        visualization_msgs::Marker marker, marker_text;
        marker.type = visualization_msgs::Marker::POINTS;
        marker.header.frame_id = s2_target_list.header.frame_id;
        marker.action = visualization_msgs::Marker::ADD;
        marker.header.stamp = s2_target_list.header.stamp;
        // marker.id = target.trackid;
        marker.id = 2;
        double x = target.position.pose.position.x;
        double y = target.position.pose.position.y;
        Eigen::Vector3d radar_pos(x,y,0.0);
        Eigen::Vector3d radar_cal_pos;
        utl_.GetTrans_cal(radar_pos,s2_x,s2_y,s2_orientation,radar_cal_pos);
        target.position.pose.position.x = radar_cal_pos.x();
        target.position.pose.position.y = radar_cal_pos.y();
        marker.points.push_back(target.position.pose.position);
        /*blue*/
        marker.color.a = 1.0f;
        marker.color.r = 0.0f;
        marker.color.g = 0.0f;
        marker.color.b = 1.0f;
        marker.ns = "s2";
        marker.scale.x = 0.3;
        marker.scale.y = 0.3;
        marker.lifetime.fromSec(0.04);
        marker_array_points.markers.push_back(marker);
        /*position text*/
        marker_text.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
        marker_text.header.frame_id = s2_target_list.header.frame_id;
        marker_text.action = visualization_msgs::Marker::ADD;
        marker_text.header.stamp = s2_target_list.header.stamp;
        //marker_text.id = target.trackid+1000;
        marker_text.id = 1002;
        marker_text.ns = "s2";
        std::string str_x = std::to_string(target.position.pose.position.x);
        std::string str_y = std::to_string(target.position.pose.position.y);
        marker_text.text = '('+str_x.substr(0,str_x.size()-5)+','+
                    str_y.substr(0,str_y.size()-5) + ')';
        marker_text.pose = target.position.pose;
        marker_text.pose.position.x = target.position.pose.position.x;
        marker_text.pose.position.y = target.position.pose.position.y - 0.5;
        marker_text.scale.z = 0.3;
        marker_text.color.a = 1.0f;
        marker_text.color.r = 0.0f;
        marker_text.color.g = 0.0f;
        marker_text.color.b = 1.0f;
        marker_text.lifetime.fromSec(0.04);
        marker_array_text.markers.push_back(marker_text);

    }
    s2_objects_pub_.publish(marker_array_points);
    s2_objects_pub_.publish(marker_array_text);
}
MatthijsBurgh commented 1 year ago

Could you generate a simple example that I can run with very less dependencies. Or maybe record a bagfile of this topic?

shyl886 commented 1 year ago

Hi Matt, I have a test again , I find if I remove the text marker array, the memory will keep stable, but if I add the text marker array, the memory will keep rising.

MatthijsBurgh commented 1 year ago

@shyl886 could you check what happens, when you combine the points and text into one single marker array msg?