[Feature-Request] Remove depthai_examples from driver compilation
I would like to be able to compile the bare minimum version of the driver and simple launch the driver. I am not interested in the examples or other features.
I already attempted this by removing the depthai_examples folder and removing the references in package.xml that list depthai_examples as a
However, when launching a camera node with:
import os
from ament_index_python.packages import get_package_share_directory
from launch_ros.actions import ComposableNodeContainer, LoadComposableNodes, Node
from launch_ros.descriptions import ComposableNode
from launch import LaunchDescription
from launch.actions import (
DeclareLaunchArgument,
IncludeLaunchDescription,
OpaqueFunction,
)
from launch.conditions import IfCondition
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
def is_launch_config_true(context, name):
return LaunchConfiguration(name).perform(context) == "true"
def setup_launch_prefix(context, *args, **kwargs):
use_gdb = LaunchConfiguration("use_gdb", default="false")
use_valgrind = LaunchConfiguration("use_valgrind", default="false")
use_perf = LaunchConfiguration("use_perf", default="false")
launch_prefix = ""
if use_gdb.perform(context) == "true":
launch_prefix += "xterm -e gdb -ex run --args"
if use_valgrind.perform(context) == "true":
launch_prefix += "valgrind --tool=callgrind"
if use_perf.perform(context) == "true":
launch_prefix += (
"perf record -g --call-graph dwarf --output=perf.out.node_name.data --"
)
return launch_prefix
def launch_setup(context, *args, **kwargs):
log_level = "info"
if context.environment.get("DEPTHAI_DEBUG") == "1":
log_level = "debug"
urdf_launch_dir = os.path.join(
get_package_share_directory("depthai_descriptions"), "launch"
)
parent_frame = LaunchConfiguration(
"parent_frame", default="oak-d-base-frame"
).perform(context)
cam_pos_x = LaunchConfiguration("cam_pos_x", default="0.0")
cam_pos_y = LaunchConfiguration("cam_pos_y", default="0.0")
cam_pos_z = LaunchConfiguration("cam_pos_z", default="0.0")
cam_roll = LaunchConfiguration("cam_roll", default="0.0")
cam_pitch = LaunchConfiguration("cam_pitch", default="0.0")
cam_yaw = LaunchConfiguration("cam_yaw", default="0.0")
use_composition = LaunchConfiguration("rsp_use_composition", default="true")
imu_from_descr = LaunchConfiguration("imu_from_descr", default="false")
publish_tf_from_calibration = LaunchConfiguration(
"publish_tf_from_calibration", default="false"
)
override_cam_model = LaunchConfiguration("override_cam_model", default="false")
config_path = PathJoinSubstitution(
[LaunchConfiguration("config_dir"), LaunchConfiguration("config_file")]
)
camera_model = LaunchConfiguration("camera_model", default="OAK-D")
rs_compat = LaunchConfiguration("rs_compat", default="false")
pointcloud_enable = LaunchConfiguration("pointcloud.enable", default="false")
rectify_rgb = LaunchConfiguration("rectify_rgb", default="true")
namespace = LaunchConfiguration("namespace", default="").perform(context)
name = LaunchConfiguration("name").perform(context)
# If RealSense compatibility is enabled, we need to override some parameters, topics and node names
parameter_overrides = {}
color_sens_name = "rgb"
stereo_sens_name = "stereo"
points_topic_name = f"{name}/points"
if pointcloud_enable.perform(context) == "true":
parameter_overrides = {
"pipeline_gen": {"i_enable_sync": True},
"rgb": {"i_synced": True},
"stereo": {"i_synced": True},
}
depth_topic_suffix = "image_raw"
if rs_compat.perform(context) == "true":
depth_topic_suffix = "image_rect_raw"
depth_profile = LaunchConfiguration("depth_module.depth_profile").perform(
context
)
color_profile = LaunchConfiguration("rgb_camera.color_profile").perform(context)
infra_profile = LaunchConfiguration("depth_module.infra_profile").perform(
context
)
# split profile string (0,0,0 or 0x0x0 or 0X0X0) into with (int) height(int) and fps(double)
# find delimiter
delimiter = ","
if "x" in depth_profile:
delimiter = "x"
elif "X" in depth_profile:
delimiter = "X"
depth_profile = depth_profile.split(delimiter)
color_profile = color_profile.split(delimiter)
infra_profile = infra_profile.split(delimiter)
color_sens_name = "color"
stereo_sens_name = "depth"
if name == "oak":
name = "camera"
points_topic_name = f"{name}/depth/color/points"
if namespace == "":
namespace = "camera"
if parent_frame == "oak-d-base-frame":
parent_frame = f"{name}_link"
parameter_overrides = {
"camera": {
"i_rs_compat": True,
},
"pipeline_gen": {
"i_enable_sync": True,
},
"color": {
"i_publish_topic": is_launch_config_true(context, "enable_color"),
"i_synced": True,
"i_width": int(color_profile[0]),
"i_height": int(color_profile[1]),
"i_fps": float(color_profile[2]),
},
"depth": {
"i_publish_topic": is_launch_config_true(context, "enable_depth"),
"i_synced": True,
"i_width": int(depth_profile[0]),
"i_height": int(depth_profile[1]),
"i_fps": float(depth_profile[2]),
},
"infra1": {
"i_width": int(infra_profile[0]),
"i_height": int(infra_profile[1]),
"i_fps": float(infra_profile[2]),
},
"infra2": {
"i_width": int(infra_profile[0]),
"i_height": int(infra_profile[1]),
"i_fps": float(infra_profile[2]),
},
}
parameter_overrides["depth"] = {
"i_left_rect_publish_topic": True,
"i_right_rect_publish_topic": True,
}
tf_params = {}
if publish_tf_from_calibration.perform(context) == "true":
cam_model = ""
if override_cam_model.perform(context) == "true":
cam_model = camera_model.perform(context)
tf_params = {
"camera": {
"i_publish_tf_from_calibration": True,
"i_tf_tf_prefix": name,
"i_tf_camera_model": cam_model,
"i_tf_base_frame": name,
"i_tf_parent_frame": parent_frame,
"i_tf_cam_pos_x": cam_pos_x.perform(context),
"i_tf_cam_pos_y": cam_pos_y.perform(context),
"i_tf_cam_pos_z": cam_pos_z.perform(context),
"i_tf_cam_roll": cam_roll.perform(context),
"i_tf_cam_pitch": cam_pitch.perform(context),
"i_tf_cam_yaw": cam_yaw.perform(context),
"i_tf_imu_from_descr": imu_from_descr.perform(context),
}
}
launch_prefix = setup_launch_prefix(context)
return [
Node(
condition=IfCondition(LaunchConfiguration("use_rviz").perform(context)),
package="rviz2",
executable="rviz2",
name="rviz2",
output="log",
arguments=["-d", LaunchConfiguration("rviz_config")],
),
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(urdf_launch_dir, "urdf_launch.py")
),
launch_arguments={
"namespace": namespace,
"tf_prefix": name,
"camera_model": camera_model,
"base_frame": name,
"parent_frame": parent_frame,
"cam_pos_x": cam_pos_x,
"cam_pos_y": cam_pos_y,
"cam_pos_z": cam_pos_z,
"cam_roll": cam_roll,
"cam_pitch": cam_pitch,
"cam_yaw": cam_yaw,
"use_composition": use_composition,
"use_base_descr": publish_tf_from_calibration,
"rs_compat": rs_compat,
}.items(),
),
ComposableNodeContainer(
name=f"{name}_container",
namespace=namespace,
package="rclcpp_components",
executable="component_container",
composable_node_descriptions=[
ComposableNode(
package="depthai_ros_driver",
plugin="depthai_ros_driver::Camera",
name=name,
namespace=namespace,
parameters=[
config_path,
tf_params,
parameter_overrides,
],
remappings=[
("/tf", f"{namespace}/tf"),
("/tf_static", f"{namespace}/tf_static"),
],
)
],
arguments=["--ros-args", "--log-level", log_level],
prefix=[launch_prefix],
output="both",
),
LoadComposableNodes(
condition=IfCondition(rectify_rgb),
target_container=f"{namespace}/{name}_container",
composable_node_descriptions=[
ComposableNode(
package="image_proc",
plugin="image_proc::RectifyNode",
name="rectify_color_node",
namespace=namespace,
remappings=[
("image", f"{name}/{color_sens_name}/image_raw"),
("camera_info", f"{name}/{color_sens_name}/camera_info"),
("image_rect", f"{name}/{color_sens_name}/image_rect"),
(
"image_rect/compressed",
f"{name}/{color_sens_name}/image_rect/compressed",
),
(
"image_rect/compressedDepth",
f"{name}/{color_sens_name}/image_rect/compressedDepth",
),
(
"image_rect/theora",
f"{name}/{color_sens_name}/image_rect/theora",
),
("/tf", f"{namespace}/tf"),
("/tf_static", f"{namespace}/tf_static"),
],
)
],
),
LoadComposableNodes(
condition=IfCondition(pointcloud_enable),
target_container=f"{namespace}/{name}_container",
composable_node_descriptions=[
ComposableNode(
package="depth_image_proc",
plugin="depth_image_proc::PointCloudXyzrgbNode",
name="point_cloud_xyzrgb_node",
namespace=namespace,
remappings=[
(
"depth_registered/image_rect",
f"{name}/{stereo_sens_name}/{depth_topic_suffix}",
),
(
"rgb/image_rect_color",
f"{name}/{color_sens_name}/image_rect",
),
("rgb/camera_info", f"{name}/{color_sens_name}/camera_info"),
("points", points_topic_name),
("/tf", f"{namespace}/tf"),
("/tf_static", f"{namespace}/tf_static"),
],
),
],
),
]
def generate_launch_description():
depthai_prefix = get_package_share_directory("depthai_ros_driver")
roboguard_prefix = get_package_share_directory("roboguard_bringup")
declared_arguments = [
DeclareLaunchArgument("name", default_value="oak"),
DeclareLaunchArgument("namespace", default_value=""),
DeclareLaunchArgument("parent_frame", default_value="oak-d-base-frame"),
DeclareLaunchArgument("camera_model", default_value="OAK-D-PRO"),
DeclareLaunchArgument("cam_pos_x", default_value="0.0"),
DeclareLaunchArgument("cam_pos_y", default_value="0.0"),
DeclareLaunchArgument("cam_pos_z", default_value="0.0"),
DeclareLaunchArgument("cam_roll", default_value="0.0"),
DeclareLaunchArgument("cam_pitch", default_value="0.0"),
DeclareLaunchArgument("cam_yaw", default_value="0.0"),
DeclareLaunchArgument("config_file", default_value=""),
DeclareLaunchArgument(
"config_dir",
default_value=os.path.join(roboguard_prefix, "config"),
),
DeclareLaunchArgument("use_rviz", default_value="false"),
DeclareLaunchArgument(
"rviz_config",
default_value=os.path.join(depthai_prefix, "config", "rviz", "rgbd.rviz"),
),
DeclareLaunchArgument("rsp_use_composition", default_value="true"),
DeclareLaunchArgument(
"publish_tf_from_calibration",
default_value="false",
description="Enables TF publishing from camera calibration file.",
),
DeclareLaunchArgument(
"imu_from_descr",
default_value="false",
description="Enables IMU publishing from URDF.",
),
DeclareLaunchArgument(
"override_cam_model",
default_value="false",
description="Overrides camera model from calibration file.",
),
DeclareLaunchArgument("use_gdb", default_value="false"),
DeclareLaunchArgument("use_valgrind", default_value="false"),
DeclareLaunchArgument("use_perf", default_value="false"),
DeclareLaunchArgument(
"rs_compat",
default_value="false",
description="Enables compatibility with RealSense nodes.",
),
DeclareLaunchArgument("rectify_rgb", default_value="true"),
DeclareLaunchArgument("pointcloud.enable", default_value="false"),
DeclareLaunchArgument("enable_color", default_value="true"),
DeclareLaunchArgument("enable_depth", default_value="true"),
DeclareLaunchArgument("enable_infra1", default_value="false"),
DeclareLaunchArgument("enable_infra2", default_value="false"),
DeclareLaunchArgument(
"depth_module.depth_profile", default_value="1280,720,30"
),
DeclareLaunchArgument("rgb_camera.color_profile", default_value="1280,720,30"),
DeclareLaunchArgument(
"depth_module.infra_profile", default_value="1280,720,30"
),
]
return LaunchDescription(
declared_arguments + [OpaqueFunction(function=launch_setup)]
)
and this config:
/**:
ros__parameters:
camera:
i_mx_id: 19443010E195A62F00
i_enable_imu: false
i_enable_ir: false
i_pipeline_type: RGB
i_usb_speed: HIGH
i_nn_type: RGB
i_fps: 25
i_ip: "192.168.131.15"
Then somehow this driver tries to load depthai_examples package and crashes.
Is there a way to completely remove depthai_examples dependency?
PS: the examples package gives another issue, and that is that it crashes on compile a lot:
130.8 [Processing: clearpath_logger_msgs, clearpath_navigation_msgs, clearpath_safety_msgs, depthai_bridge, depthai_filters, ouster_ros]
130.8 Finished <<< clearpath_logger_msgs [2min 10s]
226.2 [Processing: clearpath_navigation_msgs, clearpath_safety_msgs, depthai_bridge, depthai_filters, ouster_ros]
226.2 [Processing: clearpath_navigation_msgs, clearpath_safety_msgs, depthai_bridge, depthai_fi
lters, ouster_ros]
226.2 [Processing: clearpath_navigation_msgs, clearpath_safety_msgs, depthai_bridge, depthai_filters, ouster_ros]
226.2 Finished <<< depthai_bridge [2min 20s]
226.2 Starting >>> depthai_examples
228.5 Finished <<< clearpath_safety_msgs [3min 47s]
244.3 Finished <<< depthai_filters [2min 38s]
247.3 Finished <<< clearpath_navigation_msgs [4min 6s]
247.3 Starting >>> clearpath_dock_msgs
247.3 Starting >>> clearpath_mission_manager_msgs
247.3 Starting >>> clearpath_mission_scheduler_msgs
326.9 [Processing: clearpath_dock_msgs, clearpath_mission_manager_msgs, clearpath_mission_scheduler_msgs, depthai_examples, ouster_ros]
326.9 [Processing: clearpath_dock_msgs, clearpath_mission_manager_msgs, clearpath_mission_scheduler_msgs, depthai_examples, ouster_ros]
326.9 Finished <<< clearpath_mission_scheduler_msgs [1min 20s]
353.9 --- stderr: depthai_examples
353.9 CMake Error at CMakeLists.txt:27 (file):
353.9 file DOWNLOAD cannot compute hash on failed download
353.9
353.9 status: [28;"Timeout was reached"]
353.9
353.9
353.9 CMake Error at CMakeLists.txt:34 (file):
353.9 file DOWNLOAD cannot compute hash on failed download
353.9
353.9 status: [28;"Timeout was reached"]
353.9
353.9
353.9 ---
353.9 Failed <<< depthai_examples [2min 8s, exited with code 1]
371.6 Aborted <<< clearpath_dock_msgs [2min 4s]
410.8 Aborted <<< ouster_ros [5min 51s]
429.5 Aborted <<< clearpath_mission_manager_msgs [3min 2s]
429.5
429.5 Summary: 28 packages finished [7min 9s]
429.5 1 package failed: depthai_examples
429.5 3 packages aborted: clearpath_dock_msgs clearpath_mission_manager_msgs ouster_ros
429.5 2 packages had stderr output: depthai_examples ouster_ros
429.5 2 packages not processed
------
Dockerfile:94
--------------------
93 | # Build
94 | >>> RUN . /opt/ros/$ROS_DISTRO/setup.sh && \
95 | >>> colcon build \
96 | >>> --cmake-args -DCMAKE_BUILD_TYPE=Release \
97 | >>> -DCMAKE_CXX_FLAGS="-Wno-deprecated-declarations -Wno-deprecated"
98 |
--------------------
ERROR: failed to build: failed to solve: process "/bin/sh -c . /opt/ros/$ROS_DISTRO/setup.sh && colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS=\"-Wno-deprecated-declarations -Wno-deprecated\"" did not complete successfully: exit code: 1
My ideal solution would be to be able to skip example code.
Greetings and thank you for your time
Hi, currently in non-Kilted distributions depthai_ros_driver depends on depthai_examples for NN models (they are downloaded there), you could theoretically download the NN blob somewhere else manually and point to it in the NN config file.
Regarding the compilation crash, looks like something related to network, either lack of internet connection or some other communication error
The failing docker build was added to show that having a download step in a compile command isn't that nice to have. Is there any way to be able to compile it without requiring an internet connection?
Currently it is not supported but we could include those blobs as part of repository if required.
Hey,
I would like that, as errors like this make our build automation flaky:
212.5 --- stderr: depthai_examples
212.5 CMake Error at CMakeLists.txt:41 (file):
212.5 file DOWNLOAD cannot compute hash on failed download
212.5
212.5 status: [22;"HTTP response code said error"]
212.5
212.5
212.5 ---
212.5 Failed <<< depthai_examples [7.38s, exited with code 1]
And I understand I can make the timeout longer or trying to fix something related to internet stability / speed, but being forced to download and compile the examples along with downloading during the compile phase isn't the best design...
I hope something could be done on your end to fix this.
Thank you for your time and effort. I do love the camera and the versatility of this.
Or rather, an option to skip depth ai examples entirely. I tried manually to remove it and everything that depends on it but found out that the examples package is very intertwined with the main code. Which is also weird?