Overview
https://github.com/user-attachments/assets/5769819d-2a6d-4df5-94b2-a1d8380427e4
An self-charging routine for Stretch 4 that docks the robot in under 20 seconds, while avoiding obstacles, during daytime or night, and functions on a variety of floorings and room layouts. I describe how it works in this blog post. We welcome feedback in Github Issues or on the forum.
Quickstart
-
pip3 install hello-robot-stretch4-docking -
Setup the Jetson Coming soon
-
Put a docking station near the robot
-
Use the CLI
stretch_autodock -
Use the ROS2 docking servers
Create a map and ensure Nav2 is working. Then:
Coming Soon # ros2 launch stretch_nav2 autodocking_cpu.launch.py # # In a separate terminal: # cd stretch_nav2 # rviz2 -d rviz/autodocking_panel.rviz
Assumptions
- Robot and dock is on flat level ground
- Dock is flat against a single wall, with free space to the left and right of the dock
- Robot should not see 2 docks at the same time (they can be in different rooms)
- Robot's arm must be stowed (retracted and lowered)
Edge cases (!)
These edge cases are not supported currently. The robot may exhibit bad behavior under these conditions!
- Object on dock
- Object below dock
- Multiple docks in scene
Developing
ROS2
Coming Soon
Building your own docking pipeline (Advanced)
You can identify a dock and track it using:
from stretch4_docking.trackers import DockTracker, DockAmbiguityError
tracker = DockTracker()
tracker.warm_start() # compiles on first run, loads from cache afterwards
try:
tracker.identify(points) # Nx4 (x,y,z,intensity)
except DockAmbiguityError as e:
print('Only 1 dock allowed per room')
if tracker.is_tracking():
print(tracker.get_pose()) # SE(3) pose as (x, y, z, qx, qy, qz, qw)
You can build a egocentric costmap using:
from stretch4_docking.costmap import Costmap, RingFilter, LIDAR_LEFT_ORIGIN, LIDAR_RIGHT_ORIGIN
ring_filter = RingFilter()
ring_filter.warm_start()
costmapper = Costmap()
costmapper.warm_start()
left = ring_filter.process(left_frame.points, sensor_origin=LIDAR_LEFT_ORIGIN)
right = ring_filter.process(right_frame.points, sensor_origin=LIDAR_RIGHT_ORIGIN)
filtered_xyz = np.vstack([left[:, :3], right[:, :3]])
costmap = costmapper.process(filtered_xyz, dock_pose=tracker.get_pose())
You can servo (with collision awareness) using:
from stretch4_docking.costmap import filter_clearance_velocity
from stretch4_docking.servo import XYThetaServo
servo_law = XYThetaServo()
errx, erry, errt = error
vx, vy, wz = servo_law.step(errx, erry, errt)
filtered = filter_clearance_velocity(vx, vy, wz, costmap.obstacle_xy, costmap.cliff_xy)
robot.set_velocity(filtered.vx, filtered.vy, filtered.wz)
robot.push_command()
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hello_robot_stretch4_docking-2026.8.25.tar.gz.
File metadata
- Download URL: hello_robot_stretch4_docking-2026.8.25.tar.gz
- Upload date:
- Size: 22.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
249de3229e2f90d9cc81d7547dd447f38e84a320c13809eb0c6f6f66c04d95b7
|
|
| MD5 |
83208553117d1ca4eb90214f5e0499b3
|
|
| BLAKE2b-256 |
1e36bc16eb461e117473cd01f4d72f7e5e8d8509190e88ad1ae9f0ad3374067a
|
File details
Details for the file hello_robot_stretch4_docking-2026.8.25-py3-none-any.whl.
File metadata
- Download URL: hello_robot_stretch4_docking-2026.8.25-py3-none-any.whl
- Upload date:
- Size: 31.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6376b8948f031856644083063b70cfd389f3a87c61865163ab49f5c041266001
|
|
| MD5 |
12ece34783356a0661b1ce943bd9ad9a
|
|
| BLAKE2b-256 |
0b3edd00e97f34ae739abedd7884f43ad43d4e9432ebc8c58cb2955a7f7dbaa3
|