Водіння на відстані ================== Контроль швидкості ---------------------- Окрім налаштування зусилля двигунів трансмісії, ми також можемо налаштувати їх *швидкість*. Пам'ятайте, що зусилля не є тим самим, що швидкість. Ми також можемо попросити мотори XRP рухатися з певною швидкістю. При використанні цієї функції XRP буде активно вимірювати швидкість коліс за допомогою *енкодера* мотора. Якщо швидкість падає занадто низько, мотор автоматично збільшить зусилля, яке він застосовує, щоб знову набрати швидкість. .. tip:: Не хвилюйтеся, якщо ви ніколи не чули про *енкодер*. Ми поговоримо про них детальніше пізніше в цьому уроці. Для налаштування швидкості двигунів трансмісії ми використовуємо нову функцію: .. tab-set:: .. tab-item:: Python .. code-block:: python from XRPLib.defaults import * drivetrain.set_speed(5, 5) .. tab-item:: Blockly .. image:: media/setspeedexample.png :width: 300 Це вказує трансмісії встановити швидкість кожного колеса трансмісії для руху зі швидкістю 5 сантиметрів на секунду. Це означає, що якщо ви поставите робота на землю і дозволите обом двигунам рухатися з цією швидкістю, робот буде рухатися вперед на 5 сантиметрів щосекунди. .. admonition:: Спробуйте Додайте код до своєї програми та запустіть її. Спробуйте виконати те саме завдання, притиснувши щось до коліс вашого XRP. Зверніть увагу, що при додаванні опору двигун збільшить зусилля, щоб підтримувати постійну швидкість. Коли ви знімете опір, зусилля знову зменшаться.. Оскільки обидва колеса тепер рухаються з однаковою швидкістю, ваш робот також повинен рухатися прямо, на відміну від використання :code:`set_effort` функція. .. tip:: Якщо ви хочете, щоб робот рухався назад, використовуйте від'ємне значення швидкості, так само як ви зробили це з значенням зусилля. Проїзд на автомобілі ------------------ Ми знаємо, що за допомогою функції можна задати певну швидкість обертання коліс, але що робити, якщо ми хочемо, щоб робот проїхав певну відстань? Ми можемо задати роботові певну швидкість руху, і якщо ми знаємо, яку відстань він проїде за секунду (у цьому прикладі ми використовуємо швидкість 5 см/с), ми можемо обчислити, скільки секунд потрібно їхати, щоб проїхати цю відстань. Використаємо :math:`d` для позначення відстані, яку ми хочемо проїхати, в см. Але нам потрібне число в секундах, тому ми повинні перетворити його за допомогою *розмірного аналізу*. Для цього запишіть вираз для відомого значення з включеними одиницями виміру: .. math:: (d \text{ cm}) Розмірний аналіз передбачає множення цього виразу на спеціальні представлення числа «1» для перетворення одиниць виміру. У цьому випадку наша швидкість становить 5 см за секунду, тому ми можемо прирівняти :math:`5 \text{ cm} = 1 \text{ second}`. Перегрупувавши, ми отримаємо наше спеціальне представлення 1: .. math:: \frac{1 \text{ second}}{5 \text{ cm}} = 1 Тепер ми можемо помножити наш вираз на це спеціальне представлення числа 1: .. math:: (d \text{ cm}) \cdot \frac{1 \text{ second}}{5 \text{ cm}} Скорочуючи одиниці виміру та спрощуючи, отримуємо: .. math:: (d \cancel{\text{ cm}}) \cdot \frac{1 \text{ second}}{5 \cancel{\text{ cm}}} = \frac{d}{5} \text{ seconds} Отриманий вираз має сенс! Якщо ми хочемо просунутися на 5 см, підставляємо d = 5 і :math:`\frac{5}{5} = 1`, тож ми їдемо одну секунду. Якщо ми хочемо проїхати 2,5 см, ми підставляємо d = 2,5, і :math:`\frac{2.5}{5} = 0.5`, тож ми їдемо півсекунди. Майте на увазі, що це рівняння дійсне тільки в тому випадку, якщо робот рухається зі швидкістю 5 см в секунду. Якщо ви зміните цю швидкість на більшу або меншу, вам потрібно буде змінити знаменник дробу на цю швидкість, щоб виправити рівняння. .. admonition:: Спробуйте Обчисліть, скільки секунд потрібно, щоб проїхати один метр, якщо ваш робот рухається зі швидкістю 5 см за секунду. Пам'ятайте, що в метрі 100 см. Щоб застосувати вищевикладену теорію на практиці, нам потрібно дізнатися про нову функцію в Python: :code:`sleep`, що змушує XRP чекати кілька секунд, перш ніж перейти до наступної інструкції в коді. .. tab-set:: .. tab-item:: Python .. code-block:: python from XRPLib.defaults import * from time import sleep # We need to import the speed function to use it. drivetrain.set_speed(5, 5) sleep(x) # replace x with the time you calculated to go one meter. drivetrain.stop() # This is another function which makes it easy to stop the robot .. tab-item:: Blockly .. image:: media/setspeedandsleep.png :width: 300 .. tip:: Цей :code:`#` символ у Python створює *коментар*. Якщо ви додасте один до рядка коду, все, що йде після нього в цьому рядку, буде проігноровано роботом. Ви можете використовувати це, щоб залишати собі нотатки або швидко вимкнути рядок коду під час налагодження проблем.. У наших прикладах ми використовуємо коментарі, щоб дати вам підказки щодо написання коду. Вам не потрібно копіювати наші коментарі у свій код, але ви повинні написати свої власні, щоб легко запам'ятати, що робить ваш код. .. admonition:: Спробуйте Додайте код до своєї програми та випробуйте її. Не забудьте замінити :code:`x` на обчислене значення. Спробуйте запустити робота поруч із метровою лінійкою, щоб перевірити, наскільки точно він рухається! Цей код, який ви написали, є досить корисним, але що, якщо ви хочете проїхати інші відстані? Припустимо, що ми хочемо проїхати три відстані поспіль: 25, 50 і 75 см. Як ми можемо запрограмувати робота, щоб він це зробив? Просте рішення — скопіювати і вставити код, який ви написали раніше, тричі, і щоразу модифікувати його: .. add blockly tab once math can be inputted into "sleep" block .. code-block:: python from XRPLib.defaults import * from time import sleep # Drive 25 cm drivetrain.set_speed(5, 5) sleep(25 / 5) # Notice how we can write math directly in our program! drivetrain.stop() # Drive 50 cm drivetrain.set_speed(5, 5) sleep(50 / 5) drivetrain.stop() # Drive 75 cm drivetrain.set_speed(5, 5) sleep(75 / 5) drivetrain.stop() Це виглядає досить повторюваним. Більша частина цього коду є абсолютно однаковою. Насправді, єдина зміна між кожним блоком — це параметр, який ми передаємо до функції :code:`sleep`. Це ідеальний приклад того, навіщо нам потрібні функції. Давайте напишемо власну функцію, щоб проїхати на роботі певну відстань.. .. tab-set:: .. tab-item:: Python Python використовує ключове слово :code:`def`, щоб ви, програміст, могли повідомити йому, що ви хочете *визначити* нову функцію. Повне визначення функції виглядає так :: .. code-block:: python def function_name(parameter1, parameter2, parameter3): # put your code here # code in your function can use the parameters by name like this: print(parameter1 / 5) У цій прикладній функції є три параметри. Функції можуть мати стільки параметрів, скільки ви хочете, або навіть не мати їх взагалі. .. tab-item:: Blockly У Blockly ви створюєте функції, перетягуючи блок, який виглядає як на малюнку нижче. Інтерфейс дозволяє вам вказати ім'я функції та передати *параметри* до тіла функції. Тут ми маємо функцію під назвою some_task (яку ви повинні перейменувати відповідно до того, що робить ваша функція), яка приймає параметр під назвою :code:`text`, і використовує друкує :code:`text` значення. Функції можуть мати стільки параметрів, скільки ви хочете, або навіть не мати параметрів взагалі. .. image:: media/blocklyfunctiondefinition.png :width: 300 Нижче наведені блоки *викликають* функцію, яку ми визначили вище, щоб її виконати. Значення "Hello" передається до параметра :code:`text`, в результаті чого "Hello" виводиться на консоль.. .. image:: media/blocklyfunctioncall.png :width: 300 .. admonition:: Спробуйте Визначте функцію з назвою :code:`drive_distance` що приймає один параметр: :code:`distance_to_drive`. Використовуйте параметр у вашій функції як чисельник вашого дробу. Використовуйте свою функцію, щоб змусити робота проїхати 3 відстані поспіль. .. tip:: Визначте свої функції у верхній частині файлу, під :code:`import` оператори. Таким чином, код, що знаходиться далі у файлі, зможе їх використовувати.