For the complete documentation index, see llms.txt. This page is also available as Markdown.

Cameras

Preview from the Cameras from the command line

You can use the following tool to display the camera feeds in opencv, rerun and store them locally anywhere from the command line: stretch_camera_show.

Run stretch_camera_show --help for all the available options.

Examples:

stretch_camera_show --left --opencv # Display the left head camera only

stretch_camera_show --right --opencv # Display the right head camera only

stretch_camera_show --center --opencv # Display the center head camera only

stretch_camera_show --left_right --opencv # Display the left, right head cameras only

stretch_camera_show --left_right_center --opencv # Display the left, right and center head cameras

stretch_camera_show --gripper --rerun # Display the gripper camera feeds and the point cloud from the stereo depth

stretch_camera_show --left --recording_directory ./recordings # Store images to disk

Using the Cameras with Python

Stream-API

The camera subsystem exposes Python generators for streaming frames from the cameras. These generators yield ImageFrame or SyncedImageFrame objects.

ImageFrame is a container for a single camera's image and metadata. Access the image using the image attribute, timestamp with timestamp, and AI model results with ai_model_results.

SyncedImageFrame is a container for multiple cameras' images and metadata. You can access the individual camera frames using the left, right, and center attributes of the SyncedImageFrame object, which are ImageFrame objects.

Using one camera yields an ImageFrame.

Using multiple cameras from the head cameras simultaneously yields a SyncedImageFrame.

Stream from the gripper RGBD camera. This yields a SyncedImageFrame and populates the pointcloud field.

Preview RGBD Cameras from the command line

Run stretch_rgbd_show --help for all the available options.

Examples:

If you have ROS2 launch files running for cameras or lidars, you can use the --use_ros_for_cameras or --use_ros_for_lidar flags to use the ROS2 data instead of direct python-api access to those sensors.

Using Emulated RGBD with Python

You can capture RGBD data from the head cameras using the following scripts:

Custom AI Models (e.g. RTMO Pose Estimation)

You can pass custom AI models to the camera pipeline by wrapping them in an AIModelWrapper instance. The pipeline will automatically route imagery to your model. The results are packed in the image_frame.ai_model_results field.

Here is an example wrapping an RTMO model:

First install

Then run this example:

Here is another example wrapping a YOLOX object detection model (from rtmlib) configured to identify general COCO objects like cups, tables, desks, and chairs.

First install rtmlib:

The model weights will be automatically downloaded by rtmlib on the first run.

Calibrating your cameras

Cameras are calibrated in the factory and the calibration files are stored in the robot's home directory, under $HELLO_FLEET_PATH/$HELLO_FLEET_ID/calibration_cameras/.

If you need to re-calibrate your cameras, you can use the following tools.

First focus your camera lens using REx_camera_focus.

Then calibrate the camera intrinsics and extrinsics using REx_camera_calibrate.

The calibration process does the following:

  1. Calibrates the camera intrinsics using calibrate_camera_intrinsics. This saves the calibration yaml file that contains head_center, head_left, and head_right keys with the K and D matrices, along with other information, at $HELLO_FLEET_PATH/$HELLO_FLEET_ID/calibration_cameras/calibration_rgb_head_camera.yaml and a few other yaml files for ROS2 to work correctly.

  2. Verifies the camera intrinsics using camera_intrinsics_validate_l2_distance. This uses pre-tape-measured values to verify the camera intrinsics are correct. The values are expected to vary a little across robots, but it's a good "sanity check".

  3. Calibrates the camera-camera extrinsics using calibrate_extrinsics_cameras. This saves the calibration transforms as a yaml file containing left_to_center and right_to_center keys at $HELLO_FLEET_PATH/$HELLO_FLEET_ID/calibration_cameras/camera_extrinsics.yaml

  4. Calibrates the camera-lidar extrinsics using calibrate_extrinsics_lidars. This appends the camera-lidar extrinsics transform_right_lidar_to_head_center key to the $HELLO_FLEET_PATH/$HELLO_FLEET_ID/calibration_dual_lidar/dual_lidar_calibration.yaml file.

These values are used to estimate the distance to ArUco markers of known size using detector_aruco.py that uses cv2.solve_pnp or cv2.fisheye.solve_pnp depending on the lens type.

These values are also used by emulated_rgbd.py to create an colored point clouds and depth images using the left and right lidars, and each head camera using cv2.projectPoints or cv2.fisheye.projectPoints depending on the lens type. This also requires the lidar extrinsics to be calibrated using https://github.com/hello-robot/stretch_dual_lidar_calibration.

Calibration Controls & Offline Replay

During execution of the calibration tools (REx_camera_calibrate for camera-lidar or camera intrinsics), progression and commands can be input using either the gamepad controller or terminal keyboard inputs:

  • Gamepad Control: Tap X to capture a frame / unpause automatic movement, and hold X (for 3-4 seconds) to save the calibration to disk.

  • Keyboard Control: Type x + Enter to capture/unpause, type s + Enter to save/exit, and type q + Enter to quit without saving. This allows running calibration without a gamepad connected.

For camera-lidar calibration, you can also replay a previous session offline:

This offline replay automatically bypasses the gamepad pauses and runs through all poses automatically without requiring user input.

Last updated

Was this helpful?