Skip to content

Commit a331206

Browse files
authored
Monolithic node (#176)
monolithic node integration
1 parent 087c13b commit a331206

File tree

83 files changed

+4458
-172
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+4458
-172
lines changed

.devcontainer/devcontainer.json

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// See https://aka.ms/vscode-remote/devcontainer.json for format details.
2+
{
3+
"dockerFile": "../src/depthai-ros/Dockerfile",
4+
"build": {
5+
"args": {"BUILD_SEQUENTIAL": "1",
6+
"USE_RVIZ": "1"}
7+
},
8+
"remoteUser": "root",
9+
"runArgs": [
10+
"--device=/dev/ttyUSB0",
11+
"--privileged",
12+
"--network=host",
13+
"--cap-add=SYS_PTRACE",
14+
"--security-opt=seccomp:unconfined",
15+
"--security-opt=apparmor:unconfined",
16+
"--volume=/dev:/dev",
17+
"--volume=/tmp/.X11-unix:/tmp/.X11-unix"
18+
],
19+
"containerEnv": { "DISPLAY": "${localEnv:DISPLAY}" },
20+
// Set *default* container specific settings.json values on container create.
21+
"settings": {
22+
"terminal.integrated.profiles.linux": {
23+
"zsh": {
24+
"path": "zsh"
25+
},
26+
"bash": {
27+
"path": "bash"
28+
}
29+
30+
},
31+
"terminal.integrated.defaultProfile.linux": "zsh"
32+
},
33+
"extensions": [
34+
"dotjoshjohnson.xml",
35+
"ms-azuretools.vscode-docker",
36+
"ms-iot.vscode-ros",
37+
"ms-python.python",
38+
"ms-vscode.cpptools",
39+
"redhat.vscode-yaml",
40+
"smilerobotics.urdf",
41+
"streetsidesoftware.code-spell-checker",
42+
"twxs.cmake",
43+
"yzhang.markdown-all-in-one",
44+
"augustocdias.tasks-shell-input"
45+
]
46+
}

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
*.json
21
.vscode
32
devel
43
__pycache__

Dockerfile

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,32 @@ ENV DEBIAN_FRONTEND=noninteractive
66
RUN apt-get update \
77
&& apt-get -y install --no-install-recommends software-properties-common git libusb-1.0-0-dev wget zsh python3-colcon-common-extensions
88

9+
# using cyclone since there are some problems with discovery using fastrps & docker
10+
RUN apt install -y ros-${ROS_DISTRO}-rmw-cyclonedds-cpp
11+
912
ENV DEBIAN_FRONTEND=dialog
1013
RUN sh -c "$(wget https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)"
1114

15+
# temporary depthai install until next sync
16+
1217
ENV WS=/ws
1318
RUN mkdir -p $WS/src
14-
COPY ./ .$WS/src/depthai_ros
15-
RUN cd .$WS/ && rosdep install --from-paths src --ignore-src -y
16-
RUN if [ "$BUILD_SEQUENTIAL" = "1" ] ; then cd .$WS/ && . /opt/ros/${ROS_DISTRO}/setup.sh && colcon build --executor sequential --cmake-args -DCMAKE_BUILD_TYPE=Release ; else cd .$WS/ && . /opt/ros/${ROS_DISTRO}/setup.sh && colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release; fi
19+
COPY ./ .$WS/src/depthai-ros
20+
RUN cd .$WS/ && rosdep install --from-paths src --ignore-src --skip-keys depthai -y
21+
RUN cd /tmp && \
22+
git clone --recursive https://github.com/luxonis/depthai-core.git --branch main && \
23+
cmake -Hdepthai-core -Bdepthai-core/build -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=/usr/local && \
24+
cmake --build depthai-core/build --target install && \
25+
cd /tmp && \
26+
rm -r depthai-core
27+
28+
RUN cd .$WS/ && . /opt/ros/${ROS_DISTRO}/setup.sh && ./src/depthai-ros/build.sh -s $BUILD_SEQUENTIAL -r 1 -m 1
1729
RUN if [ "$USE_RVIZ" = "1" ] ; then echo "RVIZ ENABLED" && sudo apt install -y ros-${ROS_DISTRO}-rviz2 ros-${ROS_DISTRO}-rviz-imu-plugin ; else echo "RVIZ NOT ENABLED"; fi
1830
RUN echo "if [ -f ${WS}/install/setup.zsh ]; then source ${WS}/install/setup.zsh; fi" >> $HOME/.zshrc
1931
RUN echo 'eval "$(register-python-argcomplete3 ros2)"' >> $HOME/.zshrc
2032
RUN echo 'eval "$(register-python-argcomplete3 colcon)"' >> $HOME/.zshrc
33+
RUN echo "export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp" >> $HOME/.zshrc
2134
RUN echo "if [ -f ${WS}/install/setup.bash ]; then source ${WS}/install/setup.bash; fi" >> $HOME/.bashrc
35+
RUN echo "export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp" >> $HOME/.bashrc
2236
ENTRYPOINT [ "/ws/src/depthai_ros/entrypoint.sh" ]
2337
CMD ["zsh"]

README.md

Lines changed: 88 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
# Depthai ROS Repository
2-
Hi and welcome to the main depthai-ros respository!
2+
Hi and welcome to the main depthai-ros respository! Here you can find ROS related code for OAK cameras from Luxonis. Don't have one? You can get them [here!](https://shop.luxonis.com/)
3+
4+
Main features:
5+
6+
* You can use the cameras as classic RGBD sensors for your 3D vision needs.
7+
* You can also load Neural Networks and get the inference results straight from camera!
8+
9+
You can develop your ROS applications in following ways:
10+
11+
* Use classes provided in `depthai_bridge` to construct your own driver (see `stereo_inertial_node` example on how to do that)
12+
* Use `depthai_ros_driver` class (currently available on ROS2 Humble) to get default experience (see details below on how)
13+
14+
![](docs/segmentation.gif)
15+
316

417
Supported ROS versions:
518
- Noetic
619
- Galactic
720
- Humble
821

9-
For development check out respective git branches.
10-
11-
### Install from ros binaries
12-
13-
Add USB rules to your system
14-
```
15-
echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="03e7", MODE="0666"' | sudo tee /etc/udev/rules.d/80-movidius.rules
16-
sudo udevadm control --reload-rules && sudo udevadm trigger
17-
```
18-
Install depthai-ros. (Available for Noetic, foxy, galactic and humble)
19-
`sudo apt install ros-<distro>-depthai-ros`
22+
For usage check out respective git branches.
2023

2124
## Docker
2225
You can additionally build and run docker images on your local machine. To do that, add USB rules as in above step, clone the repository and inside it run (it matters on which branch you are on):
@@ -32,9 +35,28 @@ xhost +local:docker
3235

3336
Then you can run your image in following way:
3437
```
35-
docker run -it -v /dev/:/dev/ --privileged -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix depthai_ros
38+
docker run -it -v /dev/:/dev/ --privileged -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix depthai=ros
39+
```
40+
will run an interactive docker session. You can also try:
41+
3642
```
37-
will run an interactive docker session.
43+
docker run -it -v /dev/:/dev/ --privileged -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix depthai-ros:humble roslaunch depthai_examples stereo_inertial_node.launch.py
44+
```
45+
to run a launch file of your choice.
46+
47+
**NOTE** ROS2 Humble docker image uses Cyclone as RMW implementation.
48+
49+
50+
### Install from ros binaries
51+
52+
Add USB rules to your system
53+
```
54+
echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="03e7", MODE="0666"' | sudo tee /etc/udev/rules.d/80-movidius.rules
55+
sudo udevadm control --reload-rules && sudo udevadm trigger
56+
```
57+
Install depthai-ros. (Available for Noetic, foxy, galactic and humble)
58+
`sudo apt install ros-<distro>-depthai-ros`
59+
3860
### Running on ROS1
3961
```
4062
docker run -it -v /dev/:/dev/ --privileged -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix depthai_ros roslaunch depthai_examples stereo_inertial_node.launch
@@ -73,6 +95,49 @@ The following setup procedure assumes you have cmake version >= 3.10.2 and OpenC
7395
7. `catkin_make` (For ROS1) `colcon build` (for ROS2)
7496
8. `source devel/setup.bash` (For ROS1) & `source install/setup.bash` (for ROS2)
7597

98+
99+
### Depthai ROS Driver
100+
101+
Currently, recommended way to launch cameras is to use executables from depthai_ros_driver package.
102+
103+
This runs your camera as a ROS2 Component and gives you the ability to customize your camera using ROS parameters.
104+
Paramerers that begin with `r_` can be freely modified during runtime, for example with rqt.
105+
Parameters that begin with `i_` are set when camera is initializing, to change them you have to call `stop` and `start` services. This can be used to hot swap NNs during runtime, changing resolutions, etc. Below you can see some examples:
106+
107+
#### Setting RGB parameters
108+
![](docs/param_rgb.gif)
109+
#### Setting Stereo parameters
110+
![](docs/param_stereo.gif)
111+
#### Stopping/starting camera for power saving/reconfiguration
112+
![](docs/start_stop.gif)
113+
114+
Stopping camera also can be used for power saving, as pipeline is removed from the device. Topics are also removed when camera is stopped.
115+
116+
As for the parameters themselves, there are a few crucial ones that decide on how camera behaves.
117+
* `camera.i_pipeline_type` can be either `RGB` or `RGBD`. This tells the camera whether it should load stereo components. Default set to `RGBD`
118+
* `camera.i_nn_type` can be either `none`, `rgb` or `spatial`. This is responsible for whether the NN that we load should also take depth information (and for example provide detections in 3D format). Default set to `spatial`
119+
* `camera.i_mx_id`/`camera.i_ip` are for connecting to a specific camera. If not set, it automatically connects to the next available device.
120+
* `nn.i_nn_config_path` represents path to JSON that contains information on what type of NN to load, and what parameters to use. Currently we provide options to load MobileNet, Yolo and Segmentation (not in spatial) models. To see their example configs, navigate to `depthai_ros_driver/config/nn`. Defaults to `mobilenet.json` from `depthai_ros_driver`
121+
122+
To use provided example NN's, you can set the path to:
123+
* `depthai_ros_driver/segmentation`
124+
* `depthai_ros_driver/mobilenet`
125+
* `depthai_ros_driver/yolo`
126+
127+
All available camera-specific parameters and their default values can be seen in `depthai_ros_driver/config/camera.yaml`.
128+
129+
Currently, we provide few examples:
130+
131+
* `camera.launch.py` launches camera in RGBD, and NN in spatial (Mobilenet) mode.
132+
* `rgbd_pcl.launch.py` launches camera in basic RGBD configuration, doesn't load any NNs. Also loads ROS depth processing nodes for RGBD pointcloud.
133+
* `example_multicam.launch.py` launches several cameras at once, each one in different container. Edit the `multicam_example.yaml` config file in `config` directory to change parameters
134+
135+
![](docs/multicam.gif)
136+
* `example_segmentation.launch.py` launches camera in RGBD + semantic segmentation (pipeline type=RGBD, nn_type=rgb)
137+
* `pointcloud.launch.py` - similar to `rgbd_pcl.launch.py`, but doesn't use RGB component for pointcloud
138+
* `example_marker_publish.launch.py` launches `camera.launch.py` + small python node that publishes detected objects as markers/tfs
139+
* `rtabmap.launch.py` launches camera and RTAB-MAP RGBD SLAM (you need to install it first - `sudo apt install ros-$ROS_DISTRO-rtabmap-ros`). You might need to set manual focus via parameters here.
140+
![](docs/rtabmap.gif)
76141
## Executing an example
77142

78143
### ROS1
@@ -127,4 +192,12 @@ ros2 launch depthai_examples mobile_publisher.launch.py camera_model:=OAK-D-LITE
127192

128193
### Users can write Custom converters and plug them in for bridge Publisher.
129194
If there a standard Message or usecase for which we have not provided a ros msg or
130-
converter feel free to create a issue or reach out to us on our discord community. We would be happy to add more.
195+
converter feel free to create a issue or reach out to us on our discord community. We would be happy to add more.
196+
197+
### Developers guide
198+
199+
For easier development inside isolated workspace, one can use Visual Studio Code with DevContainers plugin, to do that:
200+
- Create separate workspace
201+
- Clone repository into src
202+
- Copy `.devcontainer` directory into main workspace directory
203+
- Open workspace directory in VSCode

build.sh

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/bin/bash
2+
Help()
3+
{
4+
echo "Build workspace"
5+
echo
6+
echo "Build options:"
7+
echo "-s [1] Set to 1 to build sequentially (longer, but saves RAM & CPU)"
8+
echo "-r [0] Set to 1 to build in Debug mode. (RelWithDebInfo)"
9+
echo "-m [0] Set to 1 to build with --merge-install option."
10+
echo
11+
}
12+
13+
sequential=1
14+
release=0
15+
merge=0
16+
build_type=Release
17+
install_type=symlink-install
18+
while getopts ":h:s:r:m:" option; do
19+
case $option in
20+
h) # display Help
21+
Help
22+
exit;;
23+
s) # Sequential executor
24+
sequential=$OPTARG;;
25+
r) # Build type
26+
release=$OPTARG;;
27+
m) # Install type
28+
merge=$OPTARG;;
29+
\?) # Invalid option
30+
echo "Error: Invalid option"
31+
exit;;
32+
esac
33+
done
34+
35+
if [ "$release" == 0 ]
36+
then
37+
build_type="RelWithDebInfo"
38+
fi
39+
40+
if [ "$merge" == 1 ]
41+
then
42+
install_type="merge-install"
43+
fi
44+
echo "Build type: $build_type, Install_type: $install_type"
45+
if [ "$sequential" == 1 ]
46+
then
47+
echo "Sequential build" && \
48+
MAKEFLAGS="-j1 -l1" colcon build \
49+
--$install_type \
50+
--executor sequential \
51+
--cmake-args -DCMAKE_BUILD_TYPE=$build_type \
52+
--cmake-args -DBUILD_TESTING=OFF \
53+
--cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
54+
--cmake-args -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
55+
--cmake-args -DBUILD_SHARED_LIBS=ON
56+
else
57+
echo "Parallel build" && \
58+
colcon build \
59+
--$install_type \
60+
--cmake-args -DCMAKE_BUILD_TYPE=$build_type \
61+
--cmake-args -DBUILD_TESTING=OFF --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON --cmake-args -DCMAKE_POSITION_INDEPENDENT_CODE=ON --cmake-args -DBUILD_SHARED_LIBS=ON
62+
fi

depthai_bridge/include/depthai_bridge/ImageConverter.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ namespace ImageMsgs = sensor_msgs::msg;
2626
using ImagePtr = ImageMsgs::Image::SharedPtr;
2727

2828
using TimePoint = std::chrono::time_point<std::chrono::steady_clock, std::chrono::steady_clock::duration>;
29-
29+
ImageMsgs::CameraInfo calibrationToCameraInfo(dai::CalibrationHandler calibHandler,
30+
dai::CameraBoardSocket cameraId,
31+
int width = -1,
32+
int height = -1,
33+
Point2f topLeftPixelId = Point2f(),
34+
Point2f bottomRightPixelId = Point2f());
3035
class ImageConverter {
3136
public:
3237
// ImageConverter() = default;

depthai_bridge/include/depthai_bridge/SpatialDetectionConverter.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "depthai/depthai.hpp"
88
#include "rclcpp/rclcpp.hpp"
9+
#include "vision_msgs/msg/detection3_d_array.hpp"
910

1011
namespace dai {
1112

@@ -20,6 +21,7 @@ class SpatialDetectionConverter {
2021
SpatialDetectionConverter(std::string frameName, int width, int height, bool normalized = false);
2122

2223
void toRosMsg(std::shared_ptr<dai::SpatialImgDetections> inNetData, std::deque<SpatialMessages::SpatialDetectionArray>& opDetectionMsg);
24+
void toRosVisionMsg(std::shared_ptr<dai::SpatialImgDetections> inNetData, std::deque<vision_msgs::msg::Detection3DArray>& opDetectionMsg);
2325

2426
SpatialDetectionArrayPtr toRosMsgPtr(std::shared_ptr<dai::SpatialImgDetections> inNetData);
2527

0 commit comments

Comments
 (0)