Area Memory ROS2

Hi,

  1. Is there a way to use the “Area Memory” feature with the ROS2 wrapper? If yes, is there any example for getting started?

  2. If we use the “Area Memory” feature and load an area file, does Zed update the area file with minor new changes that might have occurred after it was created, so the map is up to date?

  3. Can we aid its localization with Aruco/April tags? If yes, are there any examples?

Thanks, all your help is appreciated.

Hi @hey_you
Welcome to the Stereolabs community

Yes, you must set the following parameters:

Concerning the usage, I recommend you read the ZED SDK online documentation.

Yes, that’s what it does.

Sure, you can find it here: zed-ros2-examples/examples/zed_aruco_localization at master · stereolabs/zed-ros2-examples · GitHub

Hi @Myzhar Thank you so much for the warm welcome and the info on all the questions

  1. When I set the path:
        pos_tracking:
            pos_tracking_enabled: true # True to enable positional tracking from start
            pos_tracking_mode: 'GEN_3' # Matches the ZED SDK setting: 'GEN_1', 'GEN_2', 'GEN_3'
            imu_fusion: true # enable/disable IMU fusion. When set to false, only the optical odometry will be used.
            publish_tf: true # [overwritten by launch file options] publish `odom -> camera_link` TF
            publish_map_tf: true # [overwritten by launch file options] publish `map -> odom` TF
            map_frame: 'map'
            odometry_frame: 'odom'
            area_memory_db_path: '/home/me/map.area'
            area_memory: true # Enable to detect loop closure
            reset_odom_with_loop_closure: true # Re-initialize odometry to the last valid pose when loop closure happens (reset camera odometry drift)
            depth_min_range: 0.0 # Set this value for removing fixed zones of the robot in the FoV of the camerafrom the visual odometry evaluation
            set_as_static: false # If 'true' the camera will be static and not move in the environment
            set_gravity_as_origin: true # If 'true' align the positional tracking world to imu gravity measurement. Keep the yaw from the user initial pose.
            floor_alignment: false # Enable to automatically calculate camera/floor offset
            initial_base_pose: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] # Initial position of the `camera_link` frame in the map -> [X, Y, Z, R, P, Y]
            path_pub_rate: 2.0 # [DYNAMIC] - Camera trajectory publishing frequency
            path_max_count: -1 # use '-1' for unlimited path size
            two_d_mode: true # Force navigation on a plane. If true the Z value will be fixed to 'fixed_z_value', roll and pitch to zero
            fixed_z_value: 0.0 # Value to be used for Z coordinate if `two_d_mode` is true
            transform_time_offset: 0.0 # The value added to the timestamp of `map->odom` and `odom->camera_link` transform being generated
            reset_pose_with_svo_loop: true # Reset the camera pose the `initial_base_pose` when the SVO loop is enabled and the SVO playback reaches the end of the file.

It gives me an error

[component_container_isolated-2] [INFO] [1751294526.828478799] [zed.zed_node]: ===Subscribers ===
[component_container_isolated-2] [INFO] [1751294526.828933175] [zed.zed_node]:  * Plane detection: '/clicked_point'
[component_container_isolated-2] [INFO] [1751294526.906252537] [zed.zed_node]: === Starting Positional Tracking ===
[component_container_isolated-2] [INFO] [1751294526.906299778] [zed.zed_node]:  * Waiting for valid static transformations...
[component_container_isolated-2] [INFO] [1751294526.906382144] [zed.zed_node]:  Static transform ref. CMOS Sensor to Base [zed_left_camera_frame -> zed_camera_link]
[component_container_isolated-2] [INFO] [1751294526.906389448] [zed.zed_node]:   * Translation: {0.010,-0.060,-0.015}
[component_container_isolated-2] [INFO] [1751294526.906395568] [zed.zed_node]:   * Rotation: {0.000,-0.000,0.000}
[component_container_isolated-2] [INFO] [1751294526.906411204] [zed.zed_node]:  Static transform ref. CMOS Sensor to Camera Center [zed_left_camera_frame -> zed_camera_center]
[component_container_isolated-2] [INFO] [1751294526.906415392] [zed.zed_node]:   * Translation: {0.010,-0.060,0.000}
[component_container_isolated-2] [INFO] [1751294526.906419885] [zed.zed_node]:   * Rotation: {0.000,-0.000,0.000}
[component_container_isolated-2] [INFO] [1751294526.906434808] [zed.zed_node]:  Static transform Camera Center to Base [zed_camera_center -> zed_camera_link]
[component_container_isolated-2] [INFO] [1751294526.906438756] [zed.zed_node]:   * Translation: {0.000,0.000,-0.015}
[component_container_isolated-2] [INFO] [1751294526.906443240] [zed.zed_node]:   * Rotation: {0.000,-0.000,0.000}
[component_container_isolated-2] [INFO] [1751294526.907505236] [zed.zed_node]: Initial ZED left camera pose (ZED pos. tracking): 
[component_container_isolated-2] [INFO] [1751294526.907560955] [zed.zed_node]:  * T: [-0.01,0.06,0.015]
[component_container_isolated-2] [INFO] [1751294526.907570893] [zed.zed_node]:  * Q: [0,0,0,1]
[component_container_isolated-2] [WARN] [1751294526.907607157] [zed.zed_node]: 'area_memory_db_path' path doesn't exist or is unreachable: 

And if I create the area file beforehand I get the following error

[component_container_isolated-2] [INFO] [1751294595.436547016] [zed.zed_node]: ===Subscribers ===
[component_container_isolated-2] [INFO] [1751294595.437057212] [zed.zed_node]:  * Plane detection: '/clicked_point'
[component_container_isolated-2] [INFO] [1751294595.503436658] [zed.zed_node]: === Starting Positional Tracking ===
[component_container_isolated-2] [INFO] [1751294595.503494136] [zed.zed_node]:  * Waiting for valid static transformations...
[component_container_isolated-2] [INFO] [1751294595.503609285] [zed.zed_node]:  Static transform ref. CMOS Sensor to Base [zed_left_camera_frame -> zed_camera_link]
[component_container_isolated-2] [INFO] [1751294595.503625559] [zed.zed_node]:   * Translation: {0.010,-0.060,-0.015}
[component_container_isolated-2] [INFO] [1751294595.503640320] [zed.zed_node]:   * Rotation: {0.000,-0.000,0.000}
[component_container_isolated-2] [INFO] [1751294595.503663226] [zed.zed_node]:  Static transform ref. CMOS Sensor to Camera Center [zed_left_camera_frame -> zed_camera_center]
[component_container_isolated-2] [INFO] [1751294595.503674565] [zed.zed_node]:   * Translation: {0.010,-0.060,0.000}
[component_container_isolated-2] [INFO] [1751294595.503684827] [zed.zed_node]:   * Rotation: {0.000,-0.000,0.000}
[component_container_isolated-2] [INFO] [1751294595.503715770] [zed.zed_node]:  Static transform Camera Center to Base [zed_camera_center -> zed_camera_link]
[component_container_isolated-2] [INFO] [1751294595.503725494] [zed.zed_node]:   * Translation: {0.000,0.000,-0.015}
[component_container_isolated-2] [INFO] [1751294595.503735483] [zed.zed_node]:   * Rotation: {0.000,-0.000,0.000}
[component_container_isolated-2] [INFO] [1751294595.504812826] [zed.zed_node]: Initial ZED left camera pose (ZED pos. tracking): 
[component_container_isolated-2] [INFO] [1751294595.504827472] [zed.zed_node]:  * T: [-0.01,0.06,0.015]
[component_container_isolated-2] [INFO] [1751294595.504841839] [zed.zed_node]:  * Q: [0,0,0,1]
[component_container_isolated-2] [WARN] [1751294596.307794830] [zed.zed_node]: Pos. Tracking not started: INCOMPATIBLE AREA FILE
[component_container_isolated-2] [INFO] [1751294596.324623810] [zed.zed_node]: === Starting Positional Tracking ===
[component_container_isolated-2] [INFO] [1751294596.324655563] [zed.zed_node]:  * Waiting for valid static transformations...
[component_container_isolated-2] [INFO] [1751294596.325748783] [zed.zed_node]: Initial ZED left camera pose (ZED pos. tracking): 
[component_container_isolated-2] [INFO] [1751294596.325797745] [zed.zed_node]:  * T: [-0.01,0.06,0.015]
[component_container_isolated-2] [INFO] [1751294596.325808370] [zed.zed_node]:  * Q: [0,0,0,1]
[component_container_isolated-2] [WARN] [1751294597.056974644] [zed.zed_node]: Pos. Tracking not started: INCOMPATIBLE AREA FILE
[component_container_isolated-2] [INFO] [1751294597.073419943] [zed.zed_node]: === Starting Positional Tracking ===
[component_container_isolated-2] [INFO] [1751294597.073475626] [zed.zed_node]:  * Waiting for valid static transformations...
[component_container_isolated-2] [INFO] [1751294597.074541796] [zed.zed_node]: Initial ZED left camera pose (ZED pos. tracking): 
[component_container_isolated-2] [INFO] [1751294597.074563252] [zed.zed_node]:  * T: [-0.01,0.06,0.015]
[component_container_isolated-2] [INFO] [1751294597.074574060] [zed.zed_node]:  * Q: [0,0,0,1]
[component_container_isolated-2] [WARN] [1751294597.822470365] [zed.zed_node]: Pos. Tracking not started: INCOMPATIBLE AREA FILE
[component_container_isolated-2] [FATAL] [1751294597.822515590] [zed.zed_node]: It's not possible to enable the required Positional Tracking module.
[ERROR] [component_container_isolated-2]: process has died [pid 638584, exit code -11, cmd '/opt/ros/humble/lib/rclcpp_components/component_container_isolated --use_multi_threaded_executor --ros-args --log-level info --ros-args -r __node:=zed_container -r __ns:=/zed'].
^C[WARNING] [launch]: user interrupted with ctrl-c (SIGINT)
[robot_state_publisher-1] [INFO] [1751294599.984375165] [rclcpp]: signal_handler(signum=2)
[INFO] [robot_state_publisher-1]: process has finished cleanly [pid 638582]

  1. Thank you for sharing the Aruco example, I will go through it

Once again, thanks for your quick response, and all your help and support are appreciated.

Concerning the Area File handling, we need to fix it because it’s using the old ZED SDK 4 mode.
The fix will be deployed in a few days.

That’s awesome! I look forward to it. After the fix, will the above-mentioned process to save and load the map work with ROS2, or would it be different?

Thanks!

It will be the most automatic as possible.

1 Like

Hi @hey_you
you can test the new Area File handling with this GitHub PR:

You can file details on the modifications in the change log.
Any comment will be appreciated

1 Like

perfect! Thank you so much for the prompt response and the solution. I appreciate it a lot. I will test the setup and let you know if there’s any feedback.

Thanks again!

1 Like

Hi,

I have 2 questions:

  1. I have changed the params as needed
        pos_tracking:
            pos_tracking_enabled: true # True to enable positional tracking from start
            pos_tracking_mode: 'GEN_3' # Matches the ZED SDK setting: 'GEN_1', 'GEN_2', 'GEN_3'
            imu_fusion: true # enable/disable IMU fusion. When set to false, only the optical odometry will be used.
            publish_tf: true # [overwritten by launch file options] publish `odom -> camera_link` TF
            publish_map_tf: true # [overwritten by launch file options] publish `map -> odom` TF
            map_frame: 'map'
            odometry_frame: 'odom'
            area_memory: true # Enable to detect loop closure
            area_file_path: '~/test_empty_srv.area' # Path to the area memory file. If empty, the area memory will not be saved on camera closing
            save_area_memory_on_closing: true # Save Area memory before closing the camera if `area_file_path` is not empty
            reset_odom_with_loop_closure: true # Re-initialize odometry to the last valid pose when loop closure happens (reset camera odometry drift)
            depth_min_range: 0.0 # Set this value for removing fixed zones of the robot in the FoV of the camerafrom the visual odometry evaluation
            set_as_static: false # If 'true' the camera will be static and not move in the environment
            set_gravity_as_origin: true # If 'true' align the positional tracking world to imu gravity measurement. Keep the yaw from the user initial pose.
            floor_alignment: false # Enable to automatically calculate camera/floor offset
            initial_base_pose: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] # Initial position of the `camera_link` frame in the map -> [X, Y, Z, R, P, Y]
            path_pub_rate: 2.0 # [DYNAMIC] - Camera trajectory publishing frequency
            path_max_count: -1 # use '-1' for unlimited path size
            two_d_mode: true # Force navigation on a plane. If true the Z value will be fixed to 'fixed_z_value', roll and pitch to zero
            fixed_z_value: 0.0 # Value to be used for Z coordinate if `two_d_mode` is true
            transform_time_offset: 0.0 # The value added to the timestamp of `map->odom` and `odom->camera_link` transform being generated
            reset_pose_with_svo_loop: true # Reset the camera pose the `initial_base_pose` when the SVO loop is enabled and the SVO playback reaches the end of the file.

Do I need to set some parameters to ensure the position tracker is using the saved area file from the previous run?

Is it required to keep the depth mode to “neural_plus” to get possible position tracking? (I am aware that it is a function of environment too) but from parameters perspective, I’d love to know your thoughts on below posted params to get the most accurate position tracking

        depth:
            depth_mode: 'NEURAL_PLUS' # Matches the ZED SDK setting: 'NONE', 'PERFORMANCE', 'QUALITY', 'ULTRA', 'NEURAL', 'NEURAL_PLUS' - Note: if 'NONE' all the modules that requires depth extraction are disabled by default (Pos. Tracking, Obj. Detection, Mapping, ...)
            depth_stabilization: 30 # Forces positional tracking to start if major than 0 - Range: [0,100]
            openni_depth_mode: false # 'false': 32bit float [meters], 'true': 16bit unsigned int [millimeters]
            point_cloud_freq: 10.0 # [DYNAMIC] Frequency of the pointcloud publishing. This value must be equal or less than the camera framerate.
            point_cloud_res: 'COMPACT' # The resolution used for point cloud publishing - 'COMPACT'-Standard resolution. Optimizes processing and bandwidth, 'REDUCED'-Half resolution. Low processing and bandwidth requirements
            depth_confidence: 95 # [DYNAMIC]
            depth_texture_conf: 100 # [DYNAMIC]
            remove_saturated_areas: true # [DYNAMIC]
            # Other parameters are defined, according to the camera model, in the 'zed.yaml', 'zedm.yaml', 'zed2.yaml', 'zed2i.yaml'
            # 'zedx.yaml', 'zedxmini.yaml', 'virtual.yaml' files

        pos_tracking:
            pos_tracking_enabled: true # True to enable positional tracking from start
            pos_tracking_mode: 'GEN_3' # Matches the ZED SDK setting: 'GEN_1', 'GEN_2', 'GEN_3'
            imu_fusion: true # enable/disable IMU fusion. When set to false, only the optical odometry will be used.
            publish_tf: true # [overwritten by launch file options] publish `odom -> camera_link` TF
            publish_map_tf: true # [overwritten by launch file options] publish `map -> odom` TF
            map_frame: 'map'
            odometry_frame: 'odom'
            area_memory: true # Enable to detect loop closure
            area_file_path: '~/test_empty_srv.area' # Path to the area memory file. If empty, the area memory will not be saved on camera closing
            save_area_memory_on_closing: true # Save Area memory before closing the camera if `area_file_path` is not empty
            reset_odom_with_loop_closure: true # Re-initialize odometry to the last valid pose when loop closure happens (reset camera odometry drift)
            depth_min_range: 0.0 # Set this value for removing fixed zones of the robot in the FoV of the camerafrom the visual odometry evaluation
            set_as_static: false # If 'true' the camera will be static and not move in the environment
            set_gravity_as_origin: true # If 'true' align the positional tracking world to imu gravity measurement. Keep the yaw from the user initial pose.
            floor_alignment: false # Enable to automatically calculate camera/floor offset
            initial_base_pose: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] # Initial position of the `camera_link` frame in the map -> [X, Y, Z, R, P, Y]
            path_pub_rate: 2.0 # [DYNAMIC] - Camera trajectory publishing frequency
            path_max_count: -1 # use '-1' for unlimited path size
            two_d_mode: true # Force navigation on a plane. If true the Z value will be fixed to 'fixed_z_value', roll and pitch to zero
            fixed_z_value: 0.0 # Value to be used for Z coordinate if `two_d_mode` is true
            transform_time_offset: 0.0 # The value added to the timestamp of `map->odom` and `odom->camera_link` transform being generated
            reset_pose_with_svo_loop: true # Reset the camera pose the `initial_base_pose` when the SVO loop is enabled and the SVO playback reaches the end of the file.

thanks!

When you set area_file_path the Wrapper checks if the file exists or not.
If it exists and it’s valid, it’s used during Positional Tracking processing for relocalization.
If it does not exist and save_area_memory_on_closing is true, when you close the node (Ctrl+C) a new area file is created.

No, I think this is not written anywhere. NEURAL_LIGHT can be a good choice to improve processing performance.

PS I noticed that I pushed the parameters of my latest tests. The default values for the parameters in the finala version will be:

            area_memory: true # Enable to detect loop closure
            area_file_path: '' # Path to the area memory file. If empty, the area memory will not be saved on camera closing
            save_area_memory_on_closing: false # Save Area memory before closing the camera if `area_file_path` is not empty