Skip to content

Commit c9472e5

Browse files
committed
Add zed camera.
Signed-off-by: Jelmer de Wolde <[email protected]>
1 parent 7a5e947 commit c9472e5

File tree

16 files changed

+638
-7
lines changed

16 files changed

+638
-7
lines changed

.devcontainer/docker-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ services:
1717
- "/tmp/.X11-unix:/tmp/.X11-unix"
1818
- "${HOME}/.vscode-server:/home/rcdt/.vscode-server"
1919
- "../:/home/rcdt/rcdt_robotics/"
20+
- ../.cache/zed/resources:/usr/local/zed/resources
21+
- ../.cache/zed/settings:/usr/local/zed/settings
2022
- "../.personal.bashrc:/home/rcdt/.personal.bashrc"
2123
- "../.env:/home/rcdt/.env"
2224
- "../pyproject.toml:/home/rcdt/pyproject.toml"

dockerfiles/install_scripts/core_packages.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ apt install -y \
1414
git-lfs \
1515
htop \
1616
nano \
17-
python3-pip
17+
python3-pip \
18+
zstd
1819

1920
apt install -y \
2021
ros-$ROS_DISTRO-launch-pytest \
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/bin/bash -i
2+
3+
# SPDX-FileCopyrightText: Alliander N. V.
4+
#
5+
# SPDX-License-Identifier: Apache-2.0
6+
7+
# Based on dockerfile of ZED-ros2-wrapper at:
8+
# https://github.com/stereolabs/zed-ros2-wrapper/blob/e9f54907fbf41ee9ce5d54f3bb694af93dad8bb3/docker/Dockerfile.desktop-humble
9+
10+
set -e
11+
12+
UBUNTU_RELEASE_YEAR=24
13+
CUDA_MAJOR=12
14+
CUDA_MINOR=9
15+
ZED_SDK_MAJOR=5
16+
ZED_SDK_MINOR=0
17+
18+
### CUDA “version.txt” marker
19+
echo "CUDA Version ${CUDA_MAJOR}.${CUDA_MINOR}.0" > /usr/local/cuda/version.txt || true
20+
21+
### Download + install ZED SDK
22+
installer="ZED_SDK_Ubuntu${UBUNTU_RELEASE_YEAR}_cuda${CUDA_MAJOR}.${CUDA_MINOR}.run"
23+
sdk_url="https://download.stereolabs.com/zedsdk/${ZED_SDK_MAJOR}.${ZED_SDK_MINOR}/cu${CUDA_MAJOR}/ubuntu${UBUNTU_RELEASE_YEAR}"
24+
25+
echo "Downloading ${sdk_url}${installer} ..."
26+
wget -q -O "${installer}" "${sdk_url}"
27+
chmod +x "${installer}"
28+
29+
echo "Running installer …"
30+
./"${installer}" -- silent
31+
32+
chmod -R u+rwX,go+rX /usr/local/zed
33+
34+
rm -f "${installer}"
35+
rm -rf /var/lib/apt/lists/*
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/bash -i
2+
3+
# SPDX-FileCopyrightText: Alliander N. V.
4+
#
5+
# SPDX-License-Identifier: Apache-2.0
6+
7+
set -e
8+
source /home/$UNAME/.bashrc
9+
apt update
10+
11+
cd /home/$UNAME
12+
mkdir zed_ws
13+
cd /home/$UNAME/zed_ws
14+
git clone -b jazzy https://github.com/stereolabs/zed-ros2-wrapper.git src/zed_ros2_wrapper
15+
16+
sudo apt update
17+
rosdep update
18+
rosdep install --from-paths src --rosdistro $ROS_DISTRO -y -r
19+
colcon build --symlink-install --cmake-args=-DCMAKE_BUILD_TYPE=Release
20+
21+
echo "source /home/$UNAME/zed_ws/install/setup.bash" >>/home/$UNAME/.bashrc

dockerfiles/rcdt_robotics.Dockerfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ RUN ./ros2_jazzy.sh
1111
COPY ./install_scripts/core_packages.sh .
1212
RUN ./core_packages.sh
1313

14+
COPY ./install_scripts/zed_sdk.sh .
15+
RUN ./zed_sdk.sh
16+
17+
COPY ./install_scripts/zed_wrapper.sh .
18+
RUN ./zed_wrapper.sh
19+
1420
COPY ./install_scripts/franka_ros2.sh .
1521
RUN ./franka_ros2.sh
1622

docs/content/platforms.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,18 @@ A Realsense camera can be launched in simulation by creating a configuration wit
104104

105105
One can use a Realsense by connecting it with the host device using USB.
106106

107+
## ZED
108+
109+
![ZED](../img/zed/ZED.png)
110+
111+
### Simulation Zed
112+
113+
A ZED camera can be launched in simulation by creating a configuration with an *Camera* of type *zed*.
114+
115+
### Hardware Zed
116+
117+
A ZED camera can be used by connecting it to the host device via USB. To allow non-root users to access the camera, UDEV rules must be installed on the host machine. The required script can be found [here](https://gist.github.com/adujardin/2d5ce8f000fc6a7bd40bee2709749ff8).
118+
107119
## Velodyne
108120

109121
![Velodyne](../img/velodyne/velodyne.png)

docs/img/zed/ZED.png

Lines changed: 3 additions & 0 deletions
Loading

docs/img/zed/ZED.png.license

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SPDX-FileCopyrightText: Alliander N. V.
2+
3+
SPDX-License-Identifier: Apache-2.0

ros2_ws/src/rcdt_launch/launch/robots.launch.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,21 @@
2222
"",
2323
"lidar",
2424
"realsense",
25+
"zed",
2526
"franka",
2627
"franka_double",
2728
"franka_realsense",
2829
"panther",
2930
"panther_realsense",
31+
"panther_zed",
3032
"panther_lidar",
3133
"mm",
3234
"mm_lidar",
3335
],
3436
)
3537

3638

37-
def launch_setup(context: LaunchContext) -> list: # noqa: PLR0915
39+
def launch_setup(context: LaunchContext) -> list: # noqa: PLR0912, PLR0915
3840
"""Setup the launch description for the Panther robot.
3941
4042
Args:
@@ -63,6 +65,8 @@ def launch_setup(context: LaunchContext) -> list: # noqa: PLR0915
6365
Lidar("velodyne", [0, 0, 0.5])
6466
case "realsense":
6567
Camera("realsense", [0, 0, 0.5])
68+
case "zed":
69+
Camera("zed", [0, 0, 0.5], namespace="zed")
6670
case "franka":
6771
if not use_sim:
6872
Rviz.load_motion_planning_plugin = True
@@ -80,6 +84,9 @@ def launch_setup(context: LaunchContext) -> list: # noqa: PLR0915
8084
case "panther_realsense":
8185
panther = Vehicle("panther", [0, 0, 0.2])
8286
Camera("realsense", [0, 0, 0.5], parent=panther)
87+
case "panther_zed":
88+
panther = Vehicle("panther", [0, 0, 0.2])
89+
Camera("zed", [0, 0, 0.5], parent=panther)
8390
case "panther_lidar":
8491
panther = Vehicle("panther", [0, 0, 0.2], navigation=True)
8592
Lidar("velodyne", [0.13, -0.13, 0.35], parent=panther)

ros2_ws/src/rcdt_launch/rcdt_launch/robot.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,16 @@ def order_platforms() -> None:
8686
Therefore we can load all Franka robots before other platforms by rearranging the list using this method.
8787
When launching a vehicle with Nav2, lidar sensor output is required.
8888
Therefore we load a lidar before a vehicle.
89+
90+
Raises:
91+
ValueError: If an unknown platform is encountered.
8992
"""
90-
order = ["franka", "velodyne", "realsense", "panther"]
93+
order = ["franka", "velodyne", "realsense", "zed", "panther"]
94+
95+
for platform in Platform.platforms:
96+
if platform.platform not in order:
97+
raise ValueError(f"Unknown platform to order: {platform.platform}")
98+
9199
Platform.platforms = sorted(
92100
Platform.platforms, key=lambda platform: order.index(platform.platform)
93101
)
@@ -265,20 +273,22 @@ def create_map_links() -> list[Node]:
265273

266274
def __init__(
267275
self,
268-
platform: Literal["panther", "franka", "velodyne", "realsense"],
276+
platform: Literal["panther", "franka", "velodyne", "realsense", "zed"],
269277
position: list,
270278
namespace: str | None = None,
271279
parent: "Platform" | None = None,
272280
):
273281
"""Initialize a robot instance.
274282
275283
Args:
276-
platform (Literal["panther", "franka", "velodyne", "realsense"]): The platform type of the robot.
284+
platform (Literal["panther", "franka", "velodyne", "realsense", "zed"]): The platform type of the robot.
277285
position (list): The initial position of the robot.
278286
namespace (str | None): The namespace of the robot. If None, a unique namespace will be generated.
279287
parent (Platform | None): The parent robot, if any.
280288
"""
281-
self.platform: Literal["panther", "franka", "velodyne", "realsense"] = platform
289+
self.platform: Literal["panther", "franka", "velodyne", "realsense", "zed"] = (
290+
platform
291+
)
282292
self.parent = parent
283293
self.childs = []
284294
Platform.add(self)
@@ -364,6 +374,8 @@ def xacro_path(self) -> str:
364374
return get_file_path(
365375
"rcdt_sensors", ["urdf"], "rcdt_realsense_d435.urdf.xacro"
366376
)
377+
case "zed":
378+
return get_file_path("rcdt_sensors", ["urdf"], "rcdt_zed2i.urdf.xacro")
367379
case _:
368380
raise ValueError("Unknown platform.")
369381

@@ -386,6 +398,8 @@ def base_link(self) -> str:
386398
return "base_link"
387399
case "realsense":
388400
return "base_link"
401+
case "zed":
402+
return "base_link"
389403
case _:
390404
raise ValueError("Unable to provide base_link: Unknown platform.")
391405

@@ -555,8 +569,24 @@ def create_launch_description(self) -> list[RegisteredLaunchDescription]:
555569
launch_descriptions = []
556570
if self.platform == "realsense":
557571
launch_descriptions.append(self.create_realsense_launch())
572+
if self.platform == "zed":
573+
launch_descriptions.append(self.create_zed_launch())
558574
return launch_descriptions
559575

576+
def create_zed_launch(self) -> RegisteredLaunchDescription:
577+
"""Create the Zed launch description.
578+
579+
Returns:
580+
RegisteredLaunchDescription: The launch description for the Zed.
581+
"""
582+
return RegisteredLaunchDescription(
583+
get_file_path("rcdt_sensors", ["launch"], "zed.launch.py"),
584+
launch_arguments={
585+
"simulation": str(Platform.simulation),
586+
"namespace": self.namespace,
587+
},
588+
)
589+
560590
def create_realsense_launch(self) -> RegisteredLaunchDescription:
561591
"""Create the Realsense launch description.
562592

0 commit comments

Comments
 (0)