LeRobot documentation

تحميل البيئات من المستودع

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

تحميل البيئات من المستودع

تتيح لك ميزة EnvHub تحميل بيئات المحاكاة مباشرةً من Hugging Face Hub بسطر واحد من الكود. وهذا يفتح نموذجًا جديدًا وقويًا للتعاون: فبدلاً من أن تكون البيئات محبوسة داخل مكتبات ضخمة، يمكن لأي شخص نشر بيئات مخصصة ومشاركتها مع المجتمع.

ما هو EnvHub؟

يتيح لك EnvHub إنشاء بيئات محاكاة مخصصة للروبوتات باستخدام نماذج الروبوتات والسيناريوهات الخاصة بك، وجعلها سهلة الاستخدام لأي شخص من خلال إطار عمل LeRobot.

تُخزَّن حزم EnvHub على Hugging Face Hub، ويمكن سحبها واستخدامها بسلاسة في مشاريع الروبوتات الذكية الخاصة بك من خلال LeRobot بسطر واحد من الكود.

بفضل EnvHub، يمكنك:

  1. إنشاء ونشر بيئات إلى Hugging Face Hub كمستودعات Git، وتوزيع محاكيات فيزيائية معقدة دون عناء التغليف
  2. تحميل البيئات ديناميكيًا، دون تثبيتها كحزم
  3. تتبع الإصدار وتتبع التغييرات في بيئة العمل باستخدام دلالات Git
  4. اكتشف مهام المحاكاة الجديدة التي شاركها المجتمع

يعني هذا التصميم أنه يمكنك الانتقال من اكتشاف بيئة مثيرة للاهتمام على Hub إلى تشغيل التجارب في ثوانٍ، أو إنشاء روبوتك وبيئتك المخصصة دون القلق بشأن تعارضات الاعتماديات أو إجراءات التثبيت المعقدة.

عند إنشاء حزمة EnvHub، يمكنك بناء ما تشاء بداخلها واستخدام أي أداة محاكاة تفضلها: فهذا مساحتك الخاصة للتجريب. الشرط الوحيد هو أن تحتوي الحزمة على ملف env.py يحدد البيئة ويتيح لـ LeRobot تحميل حزمة EnvHub الخاصة بك واستخدامها.

يتعيّن على ملف env.py هذا أن يعرّف واجهة برمجة تطبيقات صغيرة حتى يتمكن LeRobot من تحميله وتشغيله. على وجه التحديد، يجب عليك توفير دالة make_env(n_envs: int = 1, use_async_envs: bool = False)، وهي نقطة الدخول الرئيسية لـ LeRobot. يستدعي LeRobot هذه الدالة دون إعداد، سواء محلياً أو عند تقديم الخدمة. وينبغي أن تعيد أحد ما يلي:

  • gym.vector.VectorEnv (الأكثر شيوعاً)
  • بيئة gym.Env واحدة (سيتم تغليفها تلقائيًا)
  • قاموس يربط {suite_name: {task_id: VectorEnv}} (للمعايير متعددة المهام)

بشكل افتراضي، يجب أن يكون متجه البيئة المُعاد غير مُغلّف، أي SyncVectorEnv أو AsyncVectorEnv: حيث يتولى LeRobot دوال env_fns الخاصة به ويبني كل بيئة بنفسه. يتم رفض أغلفة المتجهات المخصصة وفئاتها الفرعية بدلاً من إزالتها بصمت.

لأغلفة المتجهات المملوكة للمزوّد أو الدفعات الأصلية للوحدة المعالجة الرسومية، استخدم --env.use_native_batch=true. يحافظ هذا على بيئة المتجهات في المستودع سليمةً للتقييم المُجمَّع محلياً، بما في ذلك متطلباتها المسبقة للمعالجة. لا يمكن دمجه مع نقطة نهاية أو SimRobot. كما تحافظ واجهة برمجة التطبيقات النصية (make_env("user/repo")) على بيئة المزوّد سليمة.

قد يُعرّف env.py أيضًا قاموسًا اختياريًا LEROBOT_SIM يصف البيئة (معدل الإطارات، وضع التحكم، أسماء المكونات؛ انظر EnvHub وخادم المحاكي). وهو يُطبَّق محليًا وعند تقديم الخدمة.

البدء السريع

تحميل بيئة من Hub بسيط للغاية:

from lerobot.envs import make_env

# Load a hub environment (requires explicit consent to run remote code)
env = make_env("lerobot/cartpole-env", trust_remote_code=True)
**Security Notice**: Loading environments from the Hub executes Python code from third-party repositories. Only use `trust_remote_code=True` with repositories you trust. We strongly recommend pinning to a specific commit hash for reproducibility and security.

هيكل المستودع

لجعل بيئتك قابلة للتحميل من Hub، يجب أن يحتوي مستودعك على الحد الأدنى التالي:

الملفات المطلوبة

env.py (أو ملف بايثون مخصص)

  • يجب أن يعرّف دالة make_env(n_envs: int, use_async_envs: bool)
  • الحجج الإضافية من نوع الكلمات المفتاحية لـ make_env هي خيارات البيئة نفسها: تمرير --env.make_env_kwargs='{"episode_length": 900}' ينقلها (و--robot.env.make_env_kwargs في حالة روبوت محاكاة)، بينما يستقبلها الخادم عبر --sim.kwargs='{make_env_kwargs: {episode_length: 900}}'
  • يجب أن تُعيد هذه الدالة أحد ما يلي:
    • gym.vector.VectorEnv (الأكثر شيوعاً)
    • بيئة gym.Env واحدة (سيتم تغليفها تلقائيًا)
    • قاموس يربط {suite_name: {task_id: VectorEnv}} (للمعايير متعددة المهام)

الملفات الاختيارية

requirements.txt

  • أدرج أي تبعيات إضافية يحتاجها بيئتك
  • سيحتاج المستخدمون إلى تثبيت هذه يدويًا قبل تحميل بيئتك

LEROBOT_SIM في env.py

  • قاموس على مستوى الوحدة يصف البيئة عندما تُقدَّم بواسطة خادم المحاكي، لذا يبدأ الأمر بأمر واحد
  • كل مفتاح اختياري؛ المستودعات التي لا تحتوي على LEROBOT_SIM تستمر في العمل مع القيم الافتراضية
  • robot_type هو النوع الذي تسجّله الروبوتات الحقيقية (so_follower، omx_follower) عندما تمتلك مكتبة lerobot فئة مخصّصة لجسم الروبوت، وذلك لضمان تطابق مجموعات البيانات المحاكاة مع مجموعات البيانات الحقيقية
المفتاحالمعنىافتراضي
fpsالتحكم في معدل خطوة واحدة step()30
control_modeاتفاقية الإجراء: position أو delta أو eef_pose"position"
semanticsاسم اتفاقيات الملاحظة/الإجراء"envhub-v1"
state_namesأسماء مكوّنات observation.state، بالترتيبعام state_0، state_1، …
action_namesأسماء مكوّنات الإجراء، بالترتيبعام command_0، command_1، …
robot_typeجسم محاكى، مسجّل كمجموعة بيانات لروبوت محاكى robot_typeلا شيء (سجل البيانات sim_robot)

README.md

  • وثّق بيئتك: ما المهمة التي تنفذها، فضاءات الملاحظات/الإجراءات، المكافآت، وما إلى ذلك.
  • تضمين أمثلة على الاستخدام وأي تعليمات إعداد خاصة

.gitignore

  • استبعاد الملفات غير الضرورية من مستودعك

هيكل مستودع المثال

my-environment-repo/
├── env.py                 # Main environment definition (required)
├── requirements.txt       # Dependencies (optional)
├── README.md             # Documentation (recommended)
├── assets/               # Images, videos, etc. (optional)
│   └── demo.gif
└── configs/              # Config files if needed (optional)
    └── task_config.yaml

إنشاء مستودع البيئة الخاص بك

الخطوة 1: تعريف بيئتك

أنشئ ملف env.py يحتوي على دالة make_env:

# env.py
import gymnasium as gym

# Optional: describes the environment to the simulator server (see "Optional Files").
LEROBOT_SIM = {"fps": 50, "control_mode": "position"}

def make_env(n_envs: int = 1, use_async_envs: bool = False):
    """
    Create vectorized environments for your custom task.

    Args:
        n_envs: Number of parallel environments
        use_async_envs: Whether to use AsyncVectorEnv or SyncVectorEnv

    Returns:
        gym.vector.VectorEnv or dict mapping suite names to vectorized envs
    """
    def _make_single_env():
        # Create your custom environment
        return gym.make("CartPole-v1")

    # Choose vector environment type
    env_cls = gym.vector.AsyncVectorEnv if use_async_envs else gym.vector.SyncVectorEnv

    # Create vectorized environment
    vec_env = env_cls([_make_single_env for _ in range(n_envs)])

    return vec_env

الخطوة 2: الاختبار محليًا

قبل الرفع، اختبر بيئتك محليًا:

import numpy as np

from lerobot.envs.configs import HubEnvConfig

# Build the envs from the local folder that holds env.py, as lerobot-eval and the env server do
envs = HubEnvConfig(hub_path="./my-env", trust_remote_code=True).create_envs(n_envs=2)

# Verify it works
suite_name = next(iter(envs))
env = envs[suite_name][0]
obs, info = env.reset(seed=0)
print({key: value.shape for key, value in obs.items()})  # LeRobot keys, e.g. observation.state
env.step(np.zeros(env.action_space.shape, np.float32))
env.close()

الخطوة 3: الرفع إلى الـ Hub

ارفع مستودعك إلى Hugging Face:

# Install huggingface_hub if needed
pip install huggingface_hub

# Login to Hugging Face
hf auth login

# Create a new repository
hf repos create my-org/my-custom-env

# Initialize git and push
git init
git add .
git commit -m "Initial environment implementation"
git remote add origin https://huggingface.co/my-org/my-custom-env
git push -u origin main

أو استخدم واجهة huggingface_hub البرمجية بلغة بايثون:

from huggingface_hub import HfApi

api = HfApi()

# Create repository
api.create_repo("my-custom-env", repo_type="space")

# Upload files
api.upload_folder(
    folder_path="./my-env-folder",
    repo_id="username/my-custom-env",
    repo_type="space",
)

تحميل البيئات من المستودع

الاستخدام الأساسي

from lerobot.envs import make_env

# Load from the hub
envs_dict = make_env(
    "username/my-custom-env",
    n_envs=4,
    trust_remote_code=True
)

# Access the environment
suite_name = next(iter(envs_dict))
env = envs_dict[suite_name][0]

# Use it like any gym environment
obs, info = env.reset()
action = env.action_space.sample()
obs, reward, terminated, truncated, info = env.step(action)

متقدم: تثبيت إصدارات محددة

لضمان قابلية التكرار والأمان، ثبّت على مراجعة Git محددة:

# Pin to a specific branch
env = make_env("username/my-env@main", trust_remote_code=True)

# Pin to a specific commit (recommended for papers/experiments)
env = make_env("username/my-env@abc123def456", trust_remote_code=True)

# Pin to a tag
env = make_env("username/[email protected]", trust_remote_code=True)

مسارات الملفات المخصصة

إذا لم يكن تعريف البيئة الخاص بك في env.py:

# Load from a custom file
env = make_env("username/my-env:custom_env.py", trust_remote_code=True)

# Combine with version pinning
env = make_env("username/[email protected]:envs/task_a.py", trust_remote_code=True)

البيئات غير المتزامنة

للحصول على أداء أفضل مع بيئات متعددة:

envs_dict = make_env(
    "username/my-env",
    n_envs=8,
    use_async_envs=True,  # Use AsyncVectorEnv for parallel execution
    trust_remote_code=True
)

مرجع تنسيق عنوان URL

يدعم تنسيق عنوان URL الخاص بالمركز عدة أنماط:

النمطالوصفمثال
user/repoتحميل env.py من الفرع الرئيسيmake_env("lerobot/cartpole-env")
user/repo@revisionالتحميل من إصدار محددmake_env("lerobot/cartpole-env@main")
user/repo:pathتحميل ملف مخصصmake_env("lerobot/envs:pusht.py")
user/repo@rev:pathمراجعة + ملف مخصصmake_env("lerobot/envs@v1:pusht.py")

EnvHub وخادم المحاكاة

بشكل افتراضي، تعمل بيئات EnvHub داخل عملية التقييم: يقوم make_env بتنزيل ملف env.py الخاص بالمستودع، وتُثبَّت تبعياته بجانب LeRobot. للحفاظ على تبعيات البيئة منفصلة عن تبعيات سياستك، قدّمها باستخدام خادم المحاكي بدلاً من ذلك. أمر واحد يبني صورة تحتوي على المستودع وملف requirements.txt الخاص به، ويبدأ الخادم:

lerobot-env-server --envhub=username/my-env@<commit> --docker=true

بالإضافة إلى requirements.txt (يتم تثبيته وفق قواعد pip، لذا تعمل أسطر --extra-index-url)، يقوم هذا الصورة بتثبيت حزم apt المدرجة في ملف اختياري packages.txt، حزمة واحدة في كل سطر، كما هو الحال في Hugging Face Spaces. الصورة عبارة عن Ubuntu عادي: يأتي سائق GPU من المضيف، وتأتي مكتبات CUDA من عجلات Python التي تحتاج إليها (torch، Isaac Sim).

إن تمرير --envhub يُعد موافقة صريحة على تشغيل كود المستودع، تمامًا مثل trust_remote_code=True. ثبّت نسخة commit. ثم قيّمها ضدها كما تفعل مع أي بيئة أخرى، مع إضافة نقطة النهاية الخاصة بها:

lerobot-eval --policy.path=<checkpoint> \
  --env.type=envhub --env.hub_path=username/my-env@<commit> --env.server.endpoint=tcp/127.0.0.1:7448 \
  --rename_map='{"observation.images.front": "observation.images.camera1"}' \
  --eval.n_episodes=10

بدون --env.server.endpoint، يعمل الأمر نفسه على البيئة محليًا (مع --trust_remote_code=true)؛ ويتخذ روبوت المحاكاة نفس الخيارات تحت --robot.env.*.

تقرأ الخادم معدل التحكم واتفاقية الإجراء وأسماء المكونات من LEROBOT_SIM الخاص بالمستودع، وتستخدم القيم الافتراضية لأي عنصر لا يُصرّح به. يمكنك تجاوز قيمة معينة من سطر الأوامر، حيث تُعطى الأولوية للقيمة المُدخلة على سطر الأوامر على تلك الموجودة في المستودع، على سبيل المثال --sim.fps=15.

لكي يتم تقديم بيئة، يجب أن تتبع هذه الاتفاقيات:

  • يعيد make_env بيئات متجهية مبنية من مصانع بيئات فردية (SyncVectorEnv/AsyncVectorEnv، كما في الأمثلة أعلاه) أو بيئة gym.Env واحدة. يقوم الخادم ببناء بيئاته الخاصة من تلك المصانع وإغلاقها عند انتهاء الجلسة.
  • يُنفَّذ env.py مرة واحدة لكل عملية خادم، لذا يمكنه الاحتفاظ بحالة على مستوى العملية، مثل تطبيق محاكاة يمكن تشغيله مرة واحدة فقط (SimulationApp الخاص بـ Isaac Sim).
  • الملاحظات هي القواميس التي يقرؤها LeRobot محليًا: pixels (صورة واحدة بصيغة HWC من نوع uint8 أو قاموس للكاميرات)، وagent_pos وenvironment_state، كمصفوفات NumPy.
  • الإجراءات هي صندوق Box مستمر أحادي البُعد.
  • تنتهي الحلقات عبر terminated/truncated أو _max_episode_steps (الافتراضي 500)، ويبلّغ info["is_success"] عن النجاح. يأتي نص المهمة من خاصية task_description (أو task) للبيئة.
  • LEROBOT_SIM اختياري، لكن يُنصح بإعلانه في كل مرة لا تتطابق فيها الإعدادات الافتراضية (30 إطارًا في الثانية، التحكم في الموضع) مع بيئتك.

لمزيد من الأمثلة، راجع مجموعة بيئات EnvHub: lerobot/so101-tabletop-mujoco (MuJoCo) و lerobot/so101-tabletop-isaac (Isaac Sim، يتم تثبيته عبر requirements.txt و packages.txt) تقدّمان نفس مشهد SO-101 مع نفس الملاحظات والإجراءات و LEROBOT_SIM.

يتم تنزيل المستودع على جهازك باستخدام تسجيل الدخول الخاص بك إلى Hugging Face (HF_TOKEN أو hf auth login)، لذا تعمل المستودعات الخاصة أيضًا، ولا يرى بناء الصورة أي رمز مصادقة. كما يقبل --envhub أيضًا مجلدًا محليًا يحتوي على env.py، لتقديم بيئة قبل دفعها: lerobot-env-server --envhub=./my-env --docker=true. يعيد --build=true بناء ما تغيّر فقط: حزم apt عند تغيّر packages.txt، والمتطلبات عند تغيّر requirements.txt، وإلا فملفات المستودع فقط. اختبر بيئة جديدة محليًا أولاً (انظر الخطوة 2: الاختبار محليًا).

بيئات المهام المتعددة

بالنسبة إلى اختبارات الأداء التي تتضمن مهام متعددة (مثل LIBERO)، أعد قاموسًا متداخلًا:

def make_env(n_envs: int = 1, use_async_envs: bool = False):
    env_cls = gym.vector.AsyncVectorEnv if use_async_envs else gym.vector.SyncVectorEnv

    # Return dict: {suite_name: {task_id: VectorEnv}}
    return {
        "suite_1": {
            0: env_cls([lambda: gym.make("Task1-v0") for _ in range(n_envs)]),
            1: env_cls([lambda: gym.make("Task2-v0") for _ in range(n_envs)]),
        },
        "suite_2": {
            0: env_cls([lambda: gym.make("Task3-v0") for _ in range(n_envs)]),
        }
    }

يبني make_env كل مهمة عند استدعائه. لمحاكي GPU يتقدم بدفعة كاملة في عالم واحد (مثل Isaac Lab)، أو لمعايرة تتضمن العديد من المهام، عرّف vector_env_fns في env.py بدلاً من ذلك، كما تفعل تكاملات LeRobot الخاصة. يعيد هذا دوال إنشاء، ولا تُستدعى إلا دوال إنشاء المهام التي يتم تشغيلها:

from functools import partial


def vector_env_fns(task: str, n_envs: int, **make_env_kwargs):
    # {suite_name: {task_id: factory}}, each factory building one vector env of n_envs envs
    return {"suite_1": {0: partial(MyBatchedEnv, n_envs, "Task1"), 1: partial(MyBatchedEnv, n_envs, "Task2")}}

يجب أن يكون لكل بيئة متجهية num_envs == n_envs، وأن لا تعيد الضبط تلقائيًا (metadata["autoreset_mode"] = gym.vector.AutoresetMode.DISABLED)، وأن تُرجع الملاحظات المُجمَّعة بالصيغة المذكورة أعلاه، وأن تستقبل بذرة واحدة لكل بيئة في reset(seed=[...])، وأن تُبلّغ عن info["is_success"] لكل بيئة. تُمرَّر --env.make_env_kwargs إليها، ويستخدم كل من lerobot-eval وخادم المحاكاة هذه البيئة بدلًا من make_env. وبما أن بيئة متجهية واحدة تقوم بالفعل بخطوة كاملة على الدفعة بأكملها، فقيّم باستخدام --eval.use_async_envs=false: فعملية عاملة لن تنقل سوى دفعات الملاحظات بين العمليات، وسيبني خادم المحاكاة بيئة المحاكاة مرة ثانية داخل العملية العاملة.

اعتبارات أمنية

**Important**: The `trust_remote_code=True` flag is required to execute environment code from the Hub. This is by design for security.

عند تحميل البيئات من Hub:

  1. راجع الكود أولاً: قم بزيارة المستودع وفحص env.py قبل التحميل
  2. التثبيت على الالتزامات: استخدم رموز تجزئة التزامات محددة من أجل قابلية التكرار
  3. التحقق من التبعيات: راجع requirements.txt بحثًا عن الحزم المشبوهة
  4. استخدم مصادر موثوقة: تفضّل المؤسسات الرسمية أو الباحثين المعروفين
  5. استخدام بيئة معزولة عند الحاجة: تشغيل الأكواد غير الموثوقة في بيئات معزولة (حاويات، آلات افتراضية)

مثال على الاستخدام الآمن:

# ❌ BAD: Loading without inspection
env = make_env("random-user/untrusted-env", trust_remote_code=True)

# ✅ GOOD: Review code, then pin to specific commit
# 1. Visit https://huggingface.co/trusted-org/verified-env
# 2. Review the env.py file
# 3. Copy the commit hash
env = make_env("trusted-org/verified-env@a1b2c3d4", trust_remote_code=True)

مثال: CartPole من Hub

إليك مثالًا كاملًا يستخدم بيئة CartPole المرجعية:

from lerobot.envs import make_env
import numpy as np

# Load the environment
envs_dict = make_env("lerobot/cartpole-env", n_envs=4, trust_remote_code=True)

# Get the vectorized environment
suite_name = next(iter(envs_dict))
env = envs_dict[suite_name][0]

# Run a simple episode
obs, info = env.reset()
done = np.zeros(env.num_envs, dtype=bool)
total_reward = np.zeros(env.num_envs)

while not done.all():
    # Random policy
    action = env.action_space.sample()
    obs, reward, terminated, truncated, info = env.step(action)
    total_reward += reward
    done = terminated | truncated

print(f"Average reward: {total_reward.mean():.2f}")
env.close()

مزايا EnvHub

للمشرفين على بيئات

  • توزيع سهل: لا يتطلب تغليفًا عبر PyPI
  • التحكم في الإصدارات: استخدم Git لإدارة إصدارات البيئة
  • التكرار السريع: ادفع التحديثات فوراً
  • التوثيق: عرض ملف README الخاص بالمركز بشكل جميل
  • المجتمع: تواصل مباشرةً مع مستخدمي LeRobot

للباحثين

  • تجارب سريعة: تحميل أي بيئة في سطر واحد
  • إمكانية إعادة الإنتاج: التثبيت على التزامات محددة
  • الاكتشاف: تصفح البيئات على Hub
  • لا تعارضات: لا حاجة لتثبيت حزم متعارضة

لمجتمع

  • النظام البيئي المتنامي: مهام محاكاة أكثر تنوعاً
  • التوحيد القياسي: واجهة make_env الشائعة
  • التعاون: انسخ بيئات موجودة وحسّنها
  • إمكانية الوصول: خفض العوائق أمام مشاركة الأبحاث

استكشاف الأخطاء وإصلاحها

“رفض تنفيذ الشيفرة عن بُعد”

يجب عليك تمرير trust_remote_code=True بشكل صريح:

env = make_env("user/repo", trust_remote_code=True)

"لم يتم العثور على الوحدة X"

تتضمن بيئة المركز تبعيات تحتاج إلى تثبيتها:

# Check the repo's requirements.txt and install dependencies
pip install gymnasium numpy

“make_env not found in module”

يجب أن يعرّف ملف env.py الخاص بك دالة make_env:

def make_env(n_envs: int, use_async_envs: bool):
    # Your implementation
    pass

يعيد Environment النوع الخاطئ

يجب أن تُرجع الدالة make_env ما يلي:

  • gym.vector.VectorEnv، أو
  • بيئة gym.Env واحدة، أو
  • قاموس {suite_name: {task_id: VectorEnv}}

أفضل الممارسات

  1. وثّق بيئتك: شمل في ملف README الخاص بك أوصاف فضاءات الملاحظة/الإجراء، وهيكل المكافأة، وشروط الانتهاء
  2. إضافة requirements.txt: سرد جميع الاعتماديات مع إصداراتها
  3. إعلان LEROBOT_SIM: اسمح للبيئة بأن تُقدَّم بواسطة خادم المحاكي بأمر واحد
  4. اختبر بشكل شامل: تحقق من أن بيئتك تعمل محليًا قبل الدفع
  5. استخدام الترقيم الدلالي: وضع علامات على الإصدارات بأرقام إصدار
  6. إضافة أمثلة: تضمين أمثلة على الاستخدام في ملف README الخاص بك
  7. اجعلها بسيطة: قلّل الاعتماديات قدر الإمكان
  8. ترخيص عملك: أضف ملف LICENSE لتوضيح شروط الاستخدام

الاتجاهات المستقبلية

تمكّن منظومة EnvHub من إمكانيات مثيرة:

  • فيزياء مُسرَّعة بواسطة وحدة معالجة الرسوميات: مشاركة بيئات Isaac Gym أو Brax
  • العرض الواقعي: توزيع بيئات برسومات متقدمة
  • سيناريوهات متعددة الوكلاء: مهام تفاعل معقدة
  • محاكيات واقعية: توأم رقمي للإعدادات الفيزيائية
  • التوليد الإجرائي: تنويعات لا نهائية للمهام
  • التشويش على المجال: خطوط أنابيب DR مُهيأة مسبقًا

مع تزايد إسهامات الباحثين والمطورين، ستنمو تنوّع البيئات المتاحة وجودتها، مما يعود بالنفع على مجتمع تعلّم الروبوتات بأكمله.

انظر أيضاً

Update on GitHub