ros の勉強として usb カメラを扱ってみました。ここにメモを残します。
カメラについて
使用したカメラの情報です。
外観

商品データ
- ビデオキャプチャ解像度: 480P
- 接続: USB
- レンズ焦点距離: F6.0MM
- フォーカス範囲:20mm(最小)
- ビデオ解像度: 640 x 480
- ライン長: 最大65cm / 25.59inch
RaspberryPi の準備
Dockerfile
Dockerfile を作成します。
FROM ros:humble RUN apt update && apt install -y \ xterm \ vim \ ros-humble-usb-cam \ ros-humble-image-tools \ ros-humble-rqt-image-view \ python3-opencv \ && rm -rf /var/lib/apt/lists/* WORKDIR /root/ros2_ws COPY . /root/ros2_ws/ ENTRYPOINT ["/ros_entrypoint.sh"] CMD ["bash"]
xhost
以下のコマンドで Docker コンテナで起動した GUI を local で表示します。
Docker が動いてるのはlocal上であり、特に指定しない限り root ユーザでコンテナが生成されます。
xhost +local:root non-network local connections being added to access control list
イメージのビルド
Dockerfile を作成したディレクトリで、以下のコマンドを実行して Docker イメージをビルドします。
docker build -t my_ros2_camera .
ビルド完了後、以下のコマンドを実行して確認します。
docker images | grep my_ros2_camera my_ros2_camera latest a57967aa678b 2 hours ago 1.86GB
コンテナ起動
イメージが作成できたら、コンテナを実行します。
docker run -it --rm \
--device /dev/video0:/dev/video0 \
--privileged \
--net=host \
-e DISPLAY=$DISPLAY \
my_ros2_camera
docker コンテナ内の作業
カメラデバイスの確認
USB カメラが認識されているか確認します。
ls /dev/video*
python コード
Docker コンテナ内で USB カメラの映像を取得する Pythonノード (image_subscriber.py) を作成します。
import rclpy from rclpy.node import Node from sensor_msgs.msg import Image from cv_bridge import CvBridge import cv2 class ImageSubscriber(Node): def __init__(self): super().__init__('image_subscriber') self.subscription = self.create_subscription( Image, '/image_raw', self.image_callback, 10) self.bridge = CvBridge() def image_callback(self, msg): cv_image = self.bridge.imgmsg_to_cv2(msg, desired_encoding="bgr8") cv2.imshow("Camera", cv_image) cv2.waitKey(1) def main(args=None): rclpy.init(args=args) node = ImageSubscriber() rclpy.spin(node) node.destroy_node() rclpy.shutdown() cv2.destroyAllWindows() if __name__ == '__main__': main()
カメラノードの起動
コンテナ内で、USBカメラのノードを起動できます。
ros2 run usb_cam usb_cam_node_exe
カクカクする場合は、以下で調整します。
ros2 run usb_cam usb_cam_node_exe \ --ros-args \ -p image_width:=320 \ -p image_height:=240 \ -p framerate:=10.0 \ -p pixel_format:=yuyv \ -p io_method:=mmap
パッケージ
パッケージの作成
mkdir ~/ros2_ws/src cd ~/ros2_ws/src ros2 pkg create --build-type ament_python my_package
image_subscriber.py の場所
作成した my_package の中に image_subscriber.py を配置します。
mv ~/ros2_ws/image_subscriber.py ~/ros2_ws/src/my_package/my_package/
setup.py の編集
my_package/setup.py を開いて、entry_points に image_subscriber を追加します。
root@test-desktop:~/ros2_ws# cat src/my_package/setup.py from setuptools import find_packages, setup package_name = 'my_package' setup( name=package_name, version='0.0.0', packages=find_packages(exclude=['test']), data_files=[ ('share/ament_index/resource_index/packages', ['resource/' + package_name]), ('share/' + package_name, ['package.xml']), ], install_requires=['setuptools'], zip_safe=True, maintainer='root', maintainer_email='root@todo.todo', description='TODO: Package description', license='TODO: License declaration', tests_require=['pytest'], entry_points={ 'console_scripts': [ 'image_subscriber = my_package.image_subscriber:main', # <------------ 追加 ], }, ) root@test-desktop:~/ros2_ws#
ワークスペースをビルド
パッケージをビルドします。
cd ~/ros2_ws colcon build --packages-select my_package
ビルド後、環境変数を設定します。
source install/setup.bash
パッケージ確認
以下のコマンドで my_package がリストに表示されるか確認します。
ros2 pkg list | grep my_package my_package
ros2 run の実行
ros2 run my_package image_subscriber