ros-drivers/usb_cam

[Ros2 - Humble] Node usb_cam_node_exe failes after launching in docker container

RobinHeitz opened this issue · 6 comments

Hi there,

I've wrote a simple launch file which works native on my ubuntu 22.04 machine - can see the cam output in rviz's camera widget.
Now, I want to do the same stuff within my dev container (+ VS Code).

After ros2 launch i get the following debug output:

[DEBUG] [launch.launch_context]: emitting event synchronously: 'launch.events.IncludeLaunchDescription'
[INFO] [launch]: All log files can be found below /home/ros/.ros/log/2023-07-29-20-20-13-745148-rosmachine-3237
[INFO] [launch]: Default logging verbosity is set to DEBUG
[DEBUG] [launch]: processing event: '<launch.events.include_launch_description.IncludeLaunchDescription object at 0x7fe9c7733610>'
[DEBUG] [launch]: processing event: '<launch.events.include_launch_description.IncludeLaunchDescription object at 0x7fe9c7733610>' ✓ '<launch.event_handlers.on_include_launch_description.OnIncludeLaunchDescription object at 0x7fe9c8074df0>'
Executing <Task finished name='Task-2' coro=<LaunchService._process_one_event() done, defined at /opt/ros/humble/lib/python3.10/site-packages/launch/launch_service.py:228> result=None created at /opt/ros/humble/lib/python3.10/site-packages/launch/launch_service.py:318> took 0.106 seconds
[INFO] [usb_cam_node_exe-1]: process started with pid [3238]
[DEBUG] [launch.launch_context]: emitting event: 'launch.events.process.ProcessStarted'
[DEBUG] [launch]: processing event: '<launch.events.process.process_started.ProcessStarted object at 0x7fe9c7731990>'
[DEBUG] [launch.launch_context]: emitting event synchronously: 'launch.events.process.ProcessStderr'
[DEBUG] [launch]: processing event: '<launch.events.process.process_stderr.ProcessStderr object at 0x7fe9c7731990>'
[DEBUG] [launch]: processing event: '<launch.events.process.process_stderr.ProcessStderr object at 0x7fe9c7731990>' ✓ '<launch.event_handlers.on_process_io.OnProcessIO object at 0x7fe9c74a3cd0>'
[usb_cam_node_exe-1] [INFO] [1690662013.941405810] [camera.usb_cam]: camera_name value: test_camera
[DEBUG] [launch.launch_context]: emitting event synchronously: 'launch.events.process.ProcessStderr'
[DEBUG] [launch]: processing event: '<launch.events.process.process_stderr.ProcessStderr object at 0x7fe9c7731990>'
[DEBUG] [launch]: processing event: '<launch.events.process.process_stderr.ProcessStderr object at 0x7fe9c7731990>' ✓ '<launch.event_handlers.on_process_io.OnProcessIO object at 0x7fe9c74a3cd0>'
[usb_cam_node_exe-1] [WARN] [1690662013.941491320] [camera.usb_cam]: framerate: 15.000000
[DEBUG] [launch.launch_context]: emitting event synchronously: 'launch.events.process.ProcessStderr'
[DEBUG] [launch]: processing event: '<launch.events.process.process_stderr.ProcessStderr object at 0x7fe9c74a3fd0>'
[DEBUG] [launch]: processing event: '<launch.events.process.process_stderr.ProcessStderr object at 0x7fe9c74a3fd0>' ✓ '<launch.event_handlers.on_process_io.OnProcessIO object at 0x7fe9c74a3cd0>'
[usb_cam_node_exe-1] [INFO] [1690662013.942674808] [camera.usb_cam]: camera calibration URL: file:///workspaces/ros2_docker/ws_igmr/install/usb_cam/share/usb_cam/config/camera_info.yaml
[DEBUG] [launch.launch_context]: emitting event synchronously: 'launch.events.process.ProcessStderr'
[DEBUG] [launch]: processing event: '<launch.events.process.process_stderr.ProcessStderr object at 0x7fe9c77310f0>'
[DEBUG] [launch]: processing event: '<launch.events.process.process_stderr.ProcessStderr object at 0x7fe9c77310f0>' ✓ '<launch.event_handlers.on_process_io.OnProcessIO object at 0x7fe9c74a3cd0>'
[usb_cam_node_exe-1] [INFO] [1690662013.943085127] [camera.usb_cam]: Starting 'test_camera' (/dev/video0) at 640x480 via mmap (yuyv) at 15 FPS
[usb_cam_node_exe-1] terminate called after throwing an instance of 'char*'
[ERROR] [usb_cam_node_exe-1]: process has died [pid 3238, exit code -6, cmd '/workspaces/ros2_docker/ws_igmr/install/usb_cam/lib/usb_cam/usb_cam_node_exe --ros-args -r __node:=usb_cam -r __ns:=/camera --params-file /tmp/launch_params_fsh5lxff --params-file /tmp/launch_params_lf42zwf0 --params-file /tmp/launch_params_gzofj2cb --params-file /tmp/launch_params_7ecm4__t --params-file /tmp/launch_params_qbdqdwmv --params-file /tmp/launch_params_k4ht2r6f --params-file /tmp/launch_params_ltmmp1m1'].
[DEBUG] [launch.launch_context]: emitting event: 'launch.events.process.ProcessExited'
[DEBUG] [launch]: processing event: '<launch.events.process.process_exited.ProcessExited object at 0x7fe9c7731960>'
[DEBUG] [launch]: processing event: '<launch.events.process.process_exited.ProcessExited object at 0x7fe9c7731960>' ✓ '<launch.event_handlers.on_process_exit.OnProcessExit object at 0x7fe9c74a3ee0>'
[DEBUG] [launch]: processing event: '<launch.events.process.process_exited.ProcessExited object at 0x7fe9c7731960>' ✓ '<launch.event_handlers.on_process_exit.OnProcessExit object at 0x7fe9c74a3ac0>'
[DEBUG] [launch.launch_context]: emitting event: 'launch.events.Shutdown'
[DEBUG] [launch]: processing event: '<launch.events.shutdown.Shutdown object at 0x7fe9c77310f0>'
[DEBUG] [launch]: processing event: '<launch.events.shutdown.Shutdown object at 0x7fe9c77310f0>' ✓ '<launch.event_handlers.on_shutdown.OnShutdown object at 0x7fe9c74a2170>'
[DEBUG] [launch]: processing event: '<launch.events.shutdown.Shutdown object at 0x7fe9c77310f0>' ✓ '<launch.event_handlers.on_shutdown.OnShutdown object at 0x7fe9c8074130>'

In #169, #183 and #216 I read that

  • run container as priviledged
  • run rosdep before compiling.

rosdep install --from-paths /src --ignore-src --rosdistro humble yields that all requirements are installed.

Now to the docker side:

My devcontainer.json:


{
	"name": "ROS2-Humble_IGMR",
	"privileged": true,
	"build": {
		// Sets the run context to one level up instead of the .devcontainer folder.
		"context": "..",
		// Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename.
		"dockerfile": "../Dockerfile"
	},

	"runArgs": [
		"--name",
		"ros-dev-igmr",
		"--net=host",
        "--ipc=host",
        "-e", "DISPLAY=${env:DISPLAY}"
	],
	"remoteUser": "ros",
    "customizations": {
        "vscode": {
            "extensions":[
                "ms-vscode.cpptools",
                "ms-vscode.cpptools-themes",
                "twxs.cmake",
                "donjayamanne.python-extension-pack",
                "eamodio.gitlens",
                "ms-iot.vscode-ros"
            ]
        }
    },
	"containerEnv": {
        "DISPLAY": "unix:0",
        "ROS_LOCALHOST_ONLY": "1",
        "ROS_DOMAIN_ID": "42"
    },
	"mounts": [
		"source=/tmp/.X11-unix,target=/tmp/.X11-unix,type=bind,consistency=cached",
	]
	// "postCreateCommand": "sudo rosdep update && sudo rosdep install --from-paths src --ignore-src -y && sudo chown -R robin /home/ws/"

}

And the docker file itself:

ARG WORKSPACE=ros2_dev_ws
ARG ROS_DISTRO=humble

FROM ros:${ROS_DISTRO}


#install binary dependencies
RUN apt-get -qq update && apt-get -qq upgrade -y && apt-get install -y \
    nano \
    ros-${ROS_DISTRO}-rqt* \
    python3-pip \
    software-properties-common \
    python3-colcon-common-extensions \
    python3-rosdep \
    ros-${ROS_DISTRO}-moveit \
    ros-${ROS_DISTRO}-ros2-control \
    ros-${ROS_DISTRO}-joint-state-publisher \
    ros-${ROS_DISTRO}-joint-state-publisher-gui \
    ros-${ROS_DISTRO}-usb-cam \
    ros-${ROS_DISTRO}-aruco-opencv


RUN rm -rf /var/lib/apt/lists/*

COPY ws_igmr/src /${WORKSPACE}/src

ENV NVIDIA_VISIBLE_DEVICES \
    ${NVIDIA_VISIBLE_DEVICES:-all}
ENV NVIDIA_DRIVER_CAPABILITIES \
    ${NVIDIA_DRIVER_CAPABILITIES:+$NVIDIA_DRIVER_CAPABILITIES,}graphics
ENV QT_X11_NO_MITSHM=1
ENV EDITOR=nano
ENV XDG_RUNTIME_DIR=/tmp


ARG USERNAME=ros
ARG USER_UID=1000
ARG USER_GID=$USER_UID

# Create a non-root user
RUN groupadd --gid $USER_GID $USERNAME \
    && useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \
    # [Optional] Add sudo support for the non-root user
    && apt-get update \
    && apt-get install -y sudo \
    && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME\
    && chmod 0440 /etc/sudoers.d/$USERNAME \
    # Cleanup
    && rm -rf /var/lib/apt/lists/* \
    && echo "source /usr/share/bash-completion/completions/git" >> /home/$USERNAME/.bashrc \
    && echo "if [ -f /opt/ros/${ROS_DISTRO}/setup.bash ]; then source /opt/ros/${ROS_DISTRO}/setup.bash; fi" >> /home/$USERNAME/.bashrc


RUN echo "export DISABLE_AUTO_TITLE=true" >> /home/$USERNAME/.bashrc
RUN echo 'LC_NUMERIC="en_US.UTF-8"' >> /home/$USERNAME/.bashrc
RUN echo "source /opt/ros/humble/setup.bash" >> /home/$USERNAME/.bashrc

Should work b/c of priviledged flag, right?
In my case, the video device is /dev/video0. I tried to add --devic=/dev/video0 but that did not changed anything.
Thanks :)

I have the same (or at least a similar) problem in Foxy. Also running privileged, also seeing terminate called after throwing an instance of 'char*'.

I got it working by adding the user to the 'videos' group. This is the line I added to Dockerfile

RUN usermod -aG video ${USERNAME}

@mrdanbrooks @RobinHeitz it looks like this issue is resolved, no? I'll go ahead and close this then, feel free to reopen it if ts not

True, the mentioned Dockerfile cmd fixes the error. Thanks @mrdanbrooks

@RobinHeitz @mrdanbrooks if either of you are up for it feel free to make a PR that adds a basic Dockerfile to the ros2 branch 👍 I'd be happy to review merge that in if you guys want to!

Hi @flynneva,

I would do that, but I'm not sure about the structure.
The way I'm using it is that my complete workspace is within the docker container. Binary packages can be installed during image build, sources can be cloned.

I can add a Dockerfile, but it would not work out-of-the-box. One needs to create a directory, move his workspace (and perhabs rename it) etc. Short: It does not fit in the structure of this repo. But I can, as I said, add it and leave a comment or two in the readme.
Little disclamer: I'm not an expert, so there may be other ways