Skip to content

feat: hosted teleop over Cloudflare RT#2411

Open
ruthwikdasyam wants to merge 71 commits into
mainfrom
ruthwik/hosted-teleop
Open

feat: hosted teleop over Cloudflare RT#2411
ruthwikdasyam wants to merge 71 commits into
mainfrom
ruthwik/hosted-teleop

Conversation

@ruthwikdasyam

@ruthwikdasyam ruthwikdasyam commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Detailed in #2372

Problem

Hosted Teleop setup for DimOS

Closes DIM-XXX

Solution

Add hosted teleop over WebRTC via a Cloudflare Realtime SFU broker: a HostedTeleopModule with cmd/state datachannels + a camera video track that drops into existing blueprints, plus a shared teleop/utils recording &
transport-stats stack (recorder, latency/jitter/loss report, VideoStats).

How to Test

dimos run teleop-hosted-go2 teleop-recorder

Contributor License Agreement

  • I have read and approved the CLA.

Comment thread dimos/teleop/quest_hosted/hosted_teleop_module.py
@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Jun 10, 2026
@github-actions github-actions Bot added ready-to-merge Required CI checks have passed on this PR and removed ready-to-merge Required CI checks have passed on this PR labels Jun 10, 2026
Comment thread dimos/teleop/quest_hosted/hosted_teleop_module.py
Comment thread dimos/teleop/quest_hosted/hosted_teleop_module.py
Comment thread dimos/teleop/quest_hosted/hosted_teleop_module.py
Comment thread dimos/teleop/quest_hosted/hosted_teleop_module.py
Comment thread dimos/teleop/quest_hosted/hosted_teleop_module.py
Comment thread dimos/teleop/quest_hosted/hosted_teleop_module.py

## Sidecar files

- **`/tmp/dimos_netem_profile`** — written by `data/notes/benchmarks/netem/apply.sh`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is data/notes/benchmarks/netem/apply.sh? I see this mentioned in several places.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using netem - Network simulator to simulate degraded network conditions and testing hosted teleop metrics change. But, I am not planning on including it in this PR. Thanks for pointing this, will remove references

Comment thread dimos/teleop/quest_hosted/README.md
Comment thread dimos/teleop/quest_hosted/video_track.py
@rpc
def start(self) -> None:
# Append a per-run timestamp to the stem so each run is its own file.
base = getattr(self, "_db_path_base", None)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use getattr.

Define it as none in __init__ or on the class.

base = Path(self.config.db_path)
self._db_path_base = base
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
self.config.db_path = base.with_name(f"{base.stem}_{timestamp}{base.suffix}")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

greptile is correct. Don't mutate the config. Use self._db_path or something.

Output lands in *out_dir* if given, else next to the .db. Returns the
written report.md path. Raises if the .db is missing or unreadable.
"""
db_path = Path(db_path)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
db_path = Path(db_path)

raise FileNotFoundError(f"Recording not found: {db_path}")
if out_dir is None:
out_dir = db_path.parent
out_dir = Path(out_dir)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
out_dir = Path(out_dir)

Comment on lines +128 to +130
self._control_loop_thread: threading.Thread | None = None
self._heartbeat_thread: threading.Thread | None = None
self._telemetry_thread: threading.Thread | None = None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This module has a lot of threads. It could be simplified if you used async... but it would require rewriting multiple things. 😬

right = self._controllers.get(Hand.RIGHT)
self._publish_button_state(left, right)
except Exception:
logger.exception("Error in control loop")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An error here could potentially spam the logs with the same error over and over.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PlzReview ready-to-merge Required CI checks have passed on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants