جلسه ۸ — حلقه شبیه‌سازی

مباحث جلسه

  • stepSimulation()
  • Time Step
  • Real Time
  • سرعت شبیه‌سازی
  • مفهوم Simulation Loop

1. اول مشکل کد جلسه قبل

در جلسه ۷ داشتیم:

time.sleep(5)

این فقط به Python می‌گوید:

۵ ثانیه صبر کن.

اما Simulation را جلو نمی‌برد.

یعنی:

time.sleep(5)
      ↓
فقط منتظر بمان

در مقابل:

p.stepSimulation()

به موتور فیزیک می‌گوید:

یک گام از Simulation را محاسبه کن.

این تفاوت، هسته اصلی جلسه ۸ است.


2. stepSimulation() چیست؟

فرض کن Simulation را به فریم‌های زمانی کوچک تقسیم کنیم:

زمان:

0.000
   ↓
0.004
   ↓
0.008
   ↓
0.012
   ↓
0.016
   ↓
...

هر بار که می‌نویسیم:

p.stepSimulation()

PyBullet یک گام فیزیکی جلو می‌رود.

پس:

stepSimulation()
      ↓
محاسبه نیروها
      ↓
محاسبه حرکت
      ↓
محاسبه برخوردها
      ↓
به‌روزرسانی وضعیت اجسام
      ↓
گام بعدی

3. اولین Simulation Loop

حالا main.py را تغییر بده.

import pybullet as p
import pybullet_data
import time

print("Connecting to PyBullet...")

client = p.connect(p.GUI)

print("Connected!")
print("Connection ID:", client)

p.setAdditionalSearchPath(pybullet_data.getDataPath())

# Gravity
p.setGravity(0, 0, -9.81)

# Ground
p.loadURDF("plane.urdf")

# Collision Shape
collision_shape = p.createCollisionShape(
    p.GEOM_BOX,
    halfExtents=[0.5, 0.5, 0.5]
)

# Visual Shape
visual_shape = p.createVisualShape(
    p.GEOM_BOX,
    halfExtents=[0.5, 0.5, 0.5]
)

# Object
box_id = p.createMultiBody(
    baseMass=1,
    baseCollisionShapeIndex=collision_shape,
    baseVisualShapeIndex=visual_shape,
    basePosition=[0, 0, 2]
)

print("Box created!")

# Simulation Loop
for i in range(1000):
    p.stepSimulation()
    time.sleep(1 / 240)

p.disconnect(client)

print("Disconnected!")

4. حالا چه اتفاقی افتاد؟

این قسمت:

for i in range(1000):

یعنی:

این کار را ۱۰۰۰ بار انجام بده.

و داخل آن:

p.stepSimulation()

یعنی:

هر بار Simulation را یک گام جلو ببر.

و:

time.sleep(1 / 240)

فعلاً برای این است که اجرای حلقه را با حدود ۲۴۰ گام در ثانیه هماهنگ کنیم.

در نتیجه:

for loop
   │
   ├── stepSimulation()
   ├── sleep
   │
   ├── stepSimulation()
   ├── sleep
   │
   ├── stepSimulation()
   ├── sleep
   │
   └── ...

حالا باید ببینی مکعب از ارتفاع ۲ متر سقوط می‌کند و روی زمین قرار می‌گیرد.

نگران نباش در پایین قراره بیشتر توضیح بدیم تا مطلب جا بیاته


5. Time Step چیست؟

اینجا یک مفهوم بسیار مهم داریم.

فرض کن Time Step برابر باشد با:

1 / 240

یعنی:

0.004166... ثانیه

تقریباً ۴.۱۷ میلی‌ثانیه.

پس اگر:

p.stepSimulation()

را ۲۴۰ بار اجرا کنیم، تقریباً یک ثانیه Simulation را جلو برده‌ایم.

240 steps
   ↓
1 second simulation

این را فعلاً به شکل ساده در ذهن داشته باش:

Time Step = مقدار زمانی که Simulation با هر گام جلو می‌رود.

چرا عدد 240؟

این عدد سرعت حرکت مکعب نیست.

و حتی به این معنی نیست که مکعب باید در یک ثانیه ۲۴۰ بار حرکت کند.

وقتی می‌نویسیم:

p.stepSimulation()

یعنی:

موتور فیزیک PyBullet یک گام محاسباتی جلو برود.

ما برای شبیه‌سازی معمولاً از یک Time Step کوچک استفاده می‌کنیم.

مثلاً:

1/240 second

یعنی:

0.0041667 second

پس اگر Time Step را 1/240 بگیریم:

Simulation:
0 sec
 ↓
0.00417 sec
 ↓
0.00833 sec
 ↓
0.01250 sec
 ↓
...

240 عددی است که برای Time Step شبیه‌سازی استفاده می‌کنیم، نه سرعت مکعب.


پس چرا مکعب یک‌دفعه یک ثانیه جلو نمی‌رود؟

فرض کن بگوییم:

مکعب در یک ثانیه از ارتفاع ۲ متر سقوط کند.

اگر موتور فیزیک فقط یک بار در ثانیه وضعیت را محاسبه کند:

t=0
     ↓
   1 ثانیه
     ↓
t=1

موتور اصلاً نمی‌داند بین این دو نقطه چه اتفاقی افتاده.

اما فیزیک واقعی پیوسته است.

مکعب:

ارتفاع 2m
   ↓
1.9m
   ↓
1.8m
   ↓
1.7m
   ↓
...
   ↓
0m

بنابراین Simulation زمان را به گام‌های کوچک تقسیم می‌کند.

مثلاً:

1 second
───────────────

240 گام

1/240
1/240
1/240
...

این باعث می‌شود موتور فیزیک بتواند نیرو، سرعت، برخورد و غیره را به‌صورت عددی محاسبه کند.


ایا میشه گفت تایم استپ مثل دور کند فلم (Slow Motion) هست تا بفهمیم تو هر مرحله چه اتفاقی میافته؟!

نه . این دو مفهوم را باید جدا کنیم.

240 Hz یا Time Step کوچک برای دقت محاسبات فیزیک است، نه برای آهسته نشان دادن فیلم.

این خیلی مهم است.

مثلاً:

Physics Time Step
        ≠
Display Speed

یک مثال خیلی ساده

فرض کن یک ماشین واقعی:

سرعت = 1 m/s

یعنی در یک ثانیه:

1 متر

حرکت می‌کند.

اگر Simulation با:

dt = 1/240

کار کند، در هر گام زمانی، اگر سرعت ثابت باشد:

distance = velocity × dt

پس:

1 × 1/240
=
0.00417 m

یعنی حدود:

4.17 میلی‌متر

در هر گام.

نه در هر ثانیه!

در ۲۴۰ گام:

240 × 0.00417 ≈ 1 meter

بنابراین:

هر گام       ≈ 4.17 mm
۲۴۰ گام      ≈ 1 m

پس آن جمله قبلی من که گفتم «در یک ثانیه 0.00417 متر حرکت می‌کند» اشتباه بود. مقدار 0.00417 m مربوط به یک گام زمانی بود، نه یک ثانیه.


6. چرا Time Step برای AGV مهم است؟

فرض کن AGV ما با سرعت:

1 m/s

حرکت می‌کند.

اگر Simulation هر:

1/240 s

محاسبه شود، در هر گام تقریباً:

1 × 1/240

متر حرکت می‌کند.

یعنی حدود:

0.00417 m

یا:

4.17 mm

پس Simulation می‌تواند حرکت AGV را به صورت گام‌های بسیار کوچک محاسبه کند.


7. Simulation Time با Real Time فرق دارد

این قسمت خیلی مهم است.

دو مفهوم داریم:

Real Time

زمانی که واقعاً روی کامپیوتر می‌گذرد.

مثلاً:

10:00:00
10:00:01
10:00:02

Simulation Time

زمانی که موتور شبیه‌سازی جلو می‌رود.

مثلاً:

0.000
0.004
0.008
0.012
...

این دو الزاماً یکی نیستند.


7.1 سرعت Simulation

فرض کن Simulation ما این باشد:

Simulation Time = 10 seconds

ممکن است کامپیوتر این ۱۰ ثانیه را در:

5 seconds

محاسبه کند.

یعنی:

Real Time       = 5 sec
Simulation Time = 10 sec

پس Simulation با سرعت:

2× Real Time

اجرا شده است.

یا برعکس ممکن است کامپیوتر ضعیف باشد و:

Real Time       = 20 sec
Simulation Time = 10 sec

در این حالت Simulation کندتر از Real Time است.


8. time.sleep() این وسط چه کار می‌کند؟

این خط:

time.sleep(1 / 240)

جزء موتور فیزیک PyBullet نیست.

این دستور متعلق به Python است.

یعنی:

Python کمی صبر کن.

ما از آن استفاده می‌کنیم تا Simulation را به زمان واقعی نزدیک کنیم.

پس این دو را با هم قاطی نکن:

p.stepSimulation()

⬅️ گام فیزیکی Simulation

time.sleep(...)

⬅️ مکث واقعی CPU/برنامه


9. یک آزمایش خیلی خوب

حالا یک بار این را:

time.sleep(1 / 240)

به:

time.sleep(1 / 60)

تغییر بده.

اجرا کن.

بعد:

time.sleep(1 / 1000)

را امتحان کن.

قرار نیست فعلاً از این آزمایش نتیجه دقیق مهندسی بگیریم؛ هدف این است که رابطه سرعت اجرای حلقه با Real Time را ببینی.


11. Product-Oriented Robotics — چرا این موضوع برای محصول مهم است؟

در AGV واقعی ما یک حلقه دائمی داریم:

        ┌─────────────────────┐
        │     Read Sensors    │
        └──────────┬──────────┘
                   ↓
        ┌─────────────────────┐
        │   Decision / AI     │
        └──────────┬──────────┘
                   ↓
        ┌─────────────────────┐
        │   Motor Control     │
        └──────────┬──────────┘
                   ↓
        ┌─────────────────────┐
        │ Update Environment  │
        └──────────┬──────────┘
                   ↓
              Next Cycle
                   │
                   └──────────→

در Simulation هم یک حلقه داریم:

stepSimulation()
      ↓
Physics
      ↓
Object Position
      ↓
Collision
      ↓
Next Step

بعداً این دو حلقه را به هم نزدیک می‌کنیم.

مثلاً:

PyBullet Simulation
        │
        ▼
     Sensor
        │
        ▼
   Perception
        │
        ▼
   Decision / AI
        │
        ▼
     Control
        │
        ▼
   AGV Movement
        │
        └──────────→ Simulation

این دقیقاً همان چیزی است که بعداً برای Digital Twin و Sim-to-Real اهمیت پیدا می‌کند.


12. یک نکته بسیار مهم برای آینده

فعلاً ما از:

for i in range(1000):

استفاده می‌کنیم.

اما در پروژه واقعی AGV، نمی‌خواهیم برنامه بگوییم:

«۱۰۰۰ بار اجرا شو و تمام.»

بلکه یک Simulation Loop دائمی خواهیم داشت:

while True:
    # read sensors
    # decision
    # control
    # simulation step

البته بعداً روش حرفه‌ای‌تر و معماری درست‌تری برای این کار می‌سازیم.


جمع‌بندی جلسه ۸

تا اینجا:

stepSimulation()

یک گام فیزیکی Simulation

Time Step

مقدار زمانی که هر گام Simulation جلو می‌رود

time.sleep()

مکث واقعی Python

Real Time

زمان واقعی کامپیوتر

Simulation Time

زمان داخل دنیای شبیه‌سازی

Simulation Loop

Step
 ↓
Step
 ↓
Step
 ↓
Step
 ↓
...

و در محصول AGV:

Sensors
   ↓
Perception
   ↓
Decision
   ↓
Control
   ↓
Physics
   ↓
New State
   ↓
Sensors
   ↓
...

این حلقه، یکی از پایه‌ای‌ترین مفاهیم کل پروژه AGV ماست.

فعلاً همین کد را اجرا کن و مهم‌تر از همه ببین که مکعب واقعاً از ارتفاع ۲ متر سقوط می‌کند و روی زمین می‌ایستد. بعد از اینکه این را دیدی، می‌توانیم بخش بعدی جلسه ۸ را انجام دهیم: چگونه Time Step را خودمان کنترل کنیم و تفاوت Simulation سریع، کند و Real-Time را عملاً آزمایش کنیم.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top