طرح درس سنسورها — ربات چطور دنیا را حس می‌کند؟

ربات در لیگ شبیه‌سازی خانه هوشمند (Smart Home League) چشم و گوش ندارد؛ چند عدد دارد. هر سنسور فقط یک عدد یا یک کلمه به برنامه‌ی پایتون شما می‌دهد و کل هنر، تصمیم‌گرفتن با همان عددهاست. این صفحه سنسورها را یکی‌یکی توضیح می‌دهد: هر کدام چه می‌کند، در کد چه نامی دارد، چه چیزی برمی‌گرداند، مال کدام رده است، یک نمونه‌ی کارکردنی، و یک تمرین که همان‌جا امتحانش کنید.

این طرح درس بخشی از برنامه‌ی آموزشی آکادمی نوین ذهن است — پیشگام در طراحی و برگزاری لیگ خانه‌ی هوشمند در ایران و مسابقات فیراکاپ (FIRA). همه‌ی نمونه‌کدها روی شبیه‌ساز رسمی در همین مرورگر اجرا می‌شوند؛ لازم نیست چیزی نصب کنید.

قبل از سنسورها: ربات چطور حرکت می‌کند؟

بدون این، هیچ سنسوری به کار نمی‌آید.

ربات دو چرخ دارد و شما سرعت هرکدام را جدا تعیین می‌کنید. عدد بین -25 تا 25 است: مثبت یعنی جلو، منفی یعنی عقب.

wheelleft  = 25    # چرخ چپ، تمام سرعت جلو
wheelright = 25    # چرخ راست، تمام سرعت جلو  → مستقیم می‌رود

wheelleft  = -25   # چرخ چپ عقب
wheelright = 25    # چرخ راست جلو  → دور خودش می‌چرخد

و اگر نخواهید با چرخ‌ها سروکله بزنید، چهار دستور آماده هست. عددی که می‌دهید ثانیه‌ی واقعی است:

forward(1)     # یک ثانیه جلو
backward(0.5)  # نیم ثانیه عقب
turnleft(0.4)  # ۰٫۴ ثانیه چرخش به چپ
turnright(0.4)
stop(1)

تمرین: رباتی بنویسید که فقط مستقیم برود. ببینید چند ثانیه طول می‌کشد تا به دیوار بخورد. حالا همان را با forward(1) بنویسید و فرقش را ببینید.

۱ · سنسور فاصله — چقدر تا دیوار مانده؟

front · frontleft · frontright هر سه رده عدد، برحسب سانتی‌متر

سه سنسور اولتراسونیک رو به جلو نصب‌اند: یکی مستقیم، یکی ۳۰ درجه به چپ، یکی ۳۰ درجه به راست. هرکدام یک موج صوتی می‌فرستد و از زمان برگشتش فاصله را حساب می‌کند. عدد کوچک‌تر یعنی نزدیک‌تر. بیشترین چیزی که می‌بینند 200 سانتی‌متر است — اگر جلویش باز باشد همان ۲۰۰ را می‌دهد.

if front < 40:            # کمتر از ۴۰ سانتی‌متر تا مانع
    turnleft(0.5)
else:
    forward(1)

سه‌تا داشتن از یکی بهتر است، چون می‌شود فهمید مانع کدام طرف است و به سمت بازتر پیچید — به‌جای این‌که کورکورانه همیشه به چپ بچرخید:

if front < 40:
    if frontleft > frontright:   # سمت چپ بازتر است
        turnleft(0.4)
    else:
        turnright(0.4)
else:
    forward(1)

تمرین: عدد ۴۰ را به ۲۰ کم کنید و بعد به ۸۰ زیاد. کدام‌یک بیشتر کاشی تمیز می‌کند؟ چرا خیلی زود پیچیدن هم بد است؟

۲ · بامپر — به چیزی خوردم؟

bumperfront · bumperback · bumper هر سه رده ۰ یا ۱

دور بدنه‌ی ربات یک حلقه‌ی ضربه‌گیر هست. وقتی به چیزی می‌خورید، آن حلقه فشرده می‌شود و عدد ۱ می‌دهد. حلقه دو نیمه دارد و ربات می‌فهمد کدام نیمه خورده است:

نام در کدیعنی چه
bumperfrontبا جلوی خودم به چیزی خوردم
bumperbackاز پشت به چیزی خوردم — یا کسی به من زد
bumperهرکدام از آن دو

چرا دو تا؟ چون واکنش باید فرق کند. اگر با جلو خورده‌اید باید عقب بروید؛ اگر از پشت خورده‌اید عقب رفتن یعنی محکم‌تر خوردن.

if bumperfront == 1:
    backward(0.4)     # با جلو خوردم → عقب بکش
    turnleft(0.5)
elif bumperback == 1:
    forward(0.4)      # از پشت خوردم → برو جلو
else:
    forward(1)

تمرین: فقط با بامپر (بدون سنسور فاصله) یک ربات بنویسید که خانه را تمیز کند. کار می‌کند — ولی ببینید چقدر کندتر است. حالا بفهمید چرا سنسور فاصله ارزش دارد.

۳ · سنسور رنگ — زیر پایم چه رنگی است؟

color هر سه رده یک کلمه‌ی رنگ

زیر بدنه‌ی ربات یک سنسور رنگ هست که کف جلوی ربات را می‌بیند — یعنی رنگ را قبل از این‌که واردش شوید می‌فهمید. این مهم‌ترین نکته‌ی این سنسور است.

رنگیعنی چه
whiteکاشی تمیزنشده — امتیاز اینجاست
greenفرش بزرگ: نصف سرعت، صفر امتیاز
purpleفرش کوچک: صفر امتیاز
orange · cyanفرش‌های نشانه‌ی درها
blackدیوار یا مبلمان
red · blueکاشیِ رنگ‌شده — مال من یا مال حریف
if color == green:      # فرش بزرگ جلوتر است
    timer = 8           # هشت قدم از آن دور شو

if timer > 0:
    timer = timer - 1
    wheelleft  = -25
    wheelright = -8     # عقب‌گرد قوسی: هم دور می‌شود هم می‌چرخد

تمرین: رباتی بنویسید که فقط دنبال white بگردد و از green فرار کند. امتیازش را با ربات قبلی مقایسه کنید.

۴ · قطب‌نما — رو به کدام طرفم؟

heading U14 · U19 ۰ تا ۳۵۹ درجه

قطب‌نما می‌گوید دماغه‌ی ربات رو به کدام سمت است. عدد بین ۰ تا ۳۵۹ است:

headingجهت
0راست
90بالا
180چپ
270پایین

بدون قطب‌نما ربات نمی‌داند کجا رو کرده و مسیرش تصادفی می‌شود. با قطب‌نما می‌توانید بگویید «رو به بالا بمان» — و این تفاوت بین جاروکشیدنِ منظم و چرخیدنِ بی‌هدف است.

if heading > 95:
    turnright(0.2)      # خیلی به چپ چرخیده‌ام
elif heading < 85:
    turnleft(0.2)       # خیلی به راست چرخیده‌ام
else:
    forward(1)          # رو به بالا؛ برو

تمرین: ربات را وادار کنید مثل ماشین چمن‌زنی حرکت کند: یک خط مستقیم برود، بچرخد، خط بعدی را برگردد. بدون قطب‌نما تقریباً غیرممکن است.

۵ · شماره‌ی اتاق — الان کجای خانه‌ام؟

room U14 · U19 عدد ۰ تا ۵

خانه‌ی مسابقه شش ناحیه دارد و ربات همیشه می‌داند در کدام است:

roomکجا
0هال و پذیرایی
1آشپزخانه
2 · 3 · 4اتاق‌خواب‌ها
5سرویس بهداشتی

دم هر در یک فرش نشانه‌ی رنگی هست، تا سنسور رنگ هم بتواند در را بشناسد.

تمرین: رباتی بنویسید که در آشپزخانه (room == 1) آهسته‌تر برود چون شلوغ است، و در هال تندتر.

۶ · درصد تمیزی اتاق — این اتاق تمام شد؟

clean1 … clean5 U14 · U19 درصد، ۰ تا ۱۰۰

برای هر اتاق یک عدد دارید که می‌گوید چند درصدش رنگ شماست — لحظه‌به‌لحظه به‌روز می‌شود. این تنها سنسوری است که به شما استراتژی می‌دهد، نه فقط واکنش.

if room == 1 and clean1 > 80:
    # آشپزخانه تقریباً تمام است؛ وقت تلف نکن
    turnright(0.6)
    forward(2)         # برو سراغ اتاق بعدی

تمرین: «اتاقِ تمام‌شده را ول کن» را پیاده کنید. امتیازتان را با حالتی که این شرط را ندارید مقایسه کنید — معمولاً تفاوت چشمگیر است.

۷ · GPS — دقیقاً کجای خانه‌ام؟

x · y · goto() · distto() · angleto() U19 سانتی‌متر

در U19 ربات مختصات دقیق خودش را می‌داند و می‌تواند به یک نقطه‌ی مشخص برود. این یعنی می‌توانید مسیر طراحی کنید، نه فقط واکنش نشان دهید.

goto(300, 400)              # برو به این نقطه
d = distto(dockx, docky)    # چقدر تا ایستگاه شارژ مانده؟
a = angleto(300, 400)       # به چه زاویه‌ای باید بچرخم؟

تمرین: چهار گوشه‌ی خانه را به‌ترتیب با goto طی کنید. حالا ترتیب را عوض کنید — کدام ترتیب کوتاه‌تر است؟

۸ · باتری و ایستگاه شارژ — انرژی تمام می‌شود

battery · dockx · docky U19 درصد

در U19 باتری واقعاً خالی می‌شود و ربات با باتری خالی می‌ایستد. باید قبل از تمام شدن برگردید — و برگشتن هم انرژی می‌خواهد. این همان تصمیمی است که U19 را از U14 جدا می‌کند.

if battery < distto(dockx, docky) / 25 + 10:
    goto(dockx, docky)      # همین حالا راه بیفت وگرنه نمی‌رسی
else:
    # وقت هست؛ تمیز کن
    forward(1)

تمرین: عدد ۱۰ (حاشیه‌ی اطمینان) را کم و زیاد کنید. اگر خیلی کم باشد وسط راه می‌میرید؛ اگر خیلی زیاد باشد وقت تمیزکردن را هدر می‌دهید.

حافظه — ربات قدم قبلی را یادش می‌ماند

برنامه‌ی شما هر قدم از اول اجرا می‌شود، پس متغیرهای معمولی فراموش می‌شوند. چهار متغیر مخصوص هست که بین قدم‌ها می‌مانند — و بدون آن‌ها هیچ رفتار چندمرحله‌ای ممکن نیست:

نامکارش
timerشمارنده‌ی خودتان — «تا هشت قدم عقب برو»
stateربات الان در چه حالتی است — «۰ یعنی جاروکشی، ۱ یعنی فرار»
movetimeچرخ‌ها را برای این مدت نگه می‌دارد
stepچندمین قدم مسابقه است

اشتباه رایج: نوشتن یک واکنش بدون timer. ربات یک قدم عقب می‌رود، قدم بعد دوباره مانع را می‌بیند، دوباره یک قدم عقب — و سر جایش می‌لرزد.

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

هر سنسور به‌تنهایی ساده است. برنده کسی است که آن‌ها را کنار هم بگذارد. مثلاً «اگر جلو باز است و زیر پایم تمیزنشده است، برو» یک جمله است ولی دو سنسور دارد:

if front > 50 and color == white:
    forward(1)               # راه باز و امتیاز نگرفته → برو
elif front < 30:
    turnleft(0.4)            # مانع → بپیچ
elif color == green:
    backward(0.3)            # فرش → عقب بکش
else:
    forward(0.5)

و در U14 و بالاتر، ترکیب heading با clean1..clean5 یعنی «منظم جارو بکش و اتاق تمام‌شده را رها کن» — همان چیزی که در عمل قهرمان می‌سازد.

درباره‌ی لیگ و سازندگانش

لیگ خانه هوشمند (Smart Home League) یک مسابقه‌ی رباتیک آموزشی است که در آن دانش‌آموزان مغز یک ربات جاروبرقی را با پایتون می‌نویسند و در شبیه‌سازی خانه هوشمند (Smart Home Simulation) مقابل هم بازی می‌کنند. این لیگ توسط آکادمی نوین ذهن طراحی و برگزار می‌شود — پیشگام در این لیگ در ایران — و در مسابقات فیراکاپ (FIRA) ایران و کانادا برگزار شده است.

نیما نظریسازنده‌ی لیگ خانه هوشمند
سینا ذاکرتیم طراحی و داوری
ارشیا صادقیتیم طراحی و داوری
سنا نظریتیم طراحی و داوری