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

تتيح لك ميزة **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 وخادم المحاكي](#envhub-and-the-simulator-server)). وهو يُطبَّق محليًا وعند تقديم الخدمة.

## البدء السريع

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

```python
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)
```

  **تنبيه أمني**: يؤدي تحميل البيئات من Hub إلى تنفيذ أكواد Python من مستودعات أطراف ثالثة. استخدم `trust_remote_code=True` فقط مع المستودعات التي تثق بها. ننصح بشدة بتثبيت الإصدار على تجزئة commit محددة من أجل قابلية التكرار والأمان.

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

لجعل بيئتك قابلة للتحميل من 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`**

- قاموس على مستوى الوحدة يصف البيئة عندما تُقدَّم بواسطة [خادم المحاكي](#envhub-and-the-simulator-server)، لذا يبدأ الأمر بأمر واحد
- كل مفتاح اختياري؛ المستودعات التي لا تحتوي على `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`:

```python
# 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: الاختبار محليًا

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

```python
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:

```bash
# 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` البرمجية بلغة بايثون:

```python
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",
)
```

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

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

```python
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 محددة:

```python
# 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/my-env@v1.0.0", trust_remote_code=True)
```

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

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

```python
# 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/my-env@v1.0:envs/task_a.py", trust_remote_code=True)
```

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

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

```python
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. للحفاظ على تبعيات البيئة منفصلة عن تبعيات سياستك، قدّمها باستخدام [خادم المحاكي](./simulation) بدلاً من ذلك. أمر واحد يبني صورة تحتوي على المستودع وملف `requirements.txt` الخاص به، ويبدأ الخادم:

```bash
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. ثم قيّمها ضدها كما تفعل مع أي بيئة أخرى، مع إضافة نقطة النهاية الخاصة بها:

```bash
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`](#optional-files) الخاص بالمستودع، وتستخدم القيم الافتراضية لأي شيء لا يُعلن عنه. يمكنك تجاوز قيمة معينة من سطر الأوامر، حيث تتفوق قيمة سطر الأوامر على قيمة المستودع، على سبيل المثال `--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](https://huggingface.co/collections/lerobot/envhub-environments-6ad0f5bf3fac8dbe626c17dc): [`lerobot/so101-tabletop-mujoco`](https://huggingface.co/lerobot/so101-tabletop-mujoco) (MuJoCo) و [`lerobot/so101-tabletop-isaac`](https://huggingface.co/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: الاختبار محليًا](#step-2-test-locally)).

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

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

```python
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 الخاصة. يعيد هذا دوال إنشاء، ولا تُستدعى إلا دوال إنشاء المهام التي يتم تشغيلها:

```python
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`: فعملية عاملة لن تنقل سوى دفعات الملاحظات بين العمليات، وسيبني خادم المحاكاة بيئة المحاكاة مرة ثانية داخل العملية العاملة.

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

  **مهم**: يُشترط استخدام علم `trust_remote_code=True` لتنفيذ أكواد البيئة من Hub. وهذا مصمم على هذا النحو لأسباب أمنية.

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

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

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

```python
# ❌ 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 المرجعية:

```python
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` بشكل صريح:

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

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

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

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

### "make_env not found in module"

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

```python
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 مُهيأة مسبقًا

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

## انظر أيضاً

- [توثيق Hugging Face Hub](https://huggingface.co/docs/hub/en/index)
- [توثيق Gymnasium](https://gymnasium.farama.org/index.html)
- [مثال على بيئة Hub](https://huggingface.co/lerobot/cartpole-env)

