Як створити захоплюючу цифрову гру “М’яч у лабіринті” на вбудованому пристрої

pic

Ця сторінка покаже вам, як реалізувати вашу версію головоломки на будь-якому мікроконтролері, якщо ваш мікроконтролер має необхідне апаратне забезпечення. Деталі фактичної реалізації залишаються за вами!

Репозиторій поточної реалізації:
https://github.com/ToficE/Ball-in-maze-game/tree/master

Ідея

Ідея цього маленького проєкту з'явилася, коли троє інших студентів і я отримали завдання на проєкт відкритого типу для нашого курсу з мікропроцесорів (ECSE 444) в Університеті Макґіла.

Наш проєкт вимагав використання комплекта STM32L4S5 Discovery Kit і деяких його функцій — таких як вбудований IMU, який підключений через I2C, Калманів фільтр, ЦАП, DMA, GPIO та QSPI Flash.

Як найкраще об'єднати всі ці можливості в цікавий проєкт? І тоді нас надихнула реальна головоломка "М'яч у лабіринті".

pic

Реальна головоломка "М'яч у лабіринті"

Огляд проєкту

Ось компоненти, які вам будуть потрібні і які потрібно реалізувати в коді для створення повноцінної гри.

pic

Інерційний вимірювальний блок (IMU)

IMU — це інтегрована схема, яка часто підключається через I2C і може здійснювати вимірювання за допомогою вбудованого акселерометра або гіроскопа. Ці датчики зазвичай використовуються в додатках, які потребують визначення орієнтації та позиціонування тіла.

Ви зможете виконати цей проєкт, якщо маєте акселерометр, гіроскоп або обидва (ідеально — обидва, і ми пояснимо чому трохи пізніше).

Алгоритм цифрової обробки сигналів (DSP)

pic

Обробка даних акселерометра

Наступні обчислення виконуються для показників акселерометра:

  1. Нормалізувати вектор акселерометра

pic

  1. Визначити кути між векторами

pic

Обробка даних гіроскопа

Зазначте, що перед ініціалізацією гри необхідно виміряти зміщення гіроскопа.

Наступні обчислення виконуються для показників гіроскопа:

  1. Відняти зміщення від кожного показника
gyro_x = gyro_xyz[0] - gyro_x_bias;  
 gyro_y = gyro_xyz[1] - gyro_y_bias;
  1. Очищення нових вимірювань за допомогою фільтра Калмана
/* ФІЛЬТР НИЗЬКИХ ЧАСТОТ: видалення шуму з вимірювань гіроскопа */  
 kalman(&gyro_x_state, gyro_x);  
 kalman(&gyro_y_state, gyro_y);  

 /* отримати очищені результати */  
 gyro_x = gyro_x_state.x*GYRO_X_SENS;  
 gyro_y = gyro_y_state.x*GYRO_Y_SENS;

Фільтр Калмана часто розглядається як цифровий фільтр низьких частот, коли він налаштований на видалення шуму з вимірювань датчиків. Це описується математичною моделлю системи для оцінки невідомих змінних стану. У цьому випадку фільтр Калмана є одновимірним вектором, а станом є вимірювання гіроскопа.

  1. Інтегрувати значення за дискретним кроком часу, використовуючи поточне значення кута як константу інтеграції
/* інтегрувати для отримання кочення та нахилу з гіроскопа */  
 roll_gyro = angle_x + gyro_x * DT;  
 pitch_gyro = angle_y + gyro_y * DT;

Злиття датчиків

Нарешті, для отримання точних і чутливих вимірювань орієнтації плати, виконуємо злиття датчиків (надмножина комплементарного фільтра).

pic

де α = 0.9

 // комплементарний фільтр  
 angle_x = GYRO_ALPHA * roll_gyro + ACCEL_MAG_ALPHA * roll_acc;  
 angle_y = GYRO_ALPHA * pitch_gyro + ACCEL_MAG_ALPHA * pitch_acc;

Ви можете або не використовувати злиття датчиків, або застосовувати лише один з двох датчиків.
Але очікуйте, що ваші результати будуть менш точними і, можливо, шумними.

Тестування

Тестування проводилось за допомогою можливостей графіку трасування часу SWV у IDE для STM32.

pic

Алгоритм кінематики

Цей алгоритм використовується для визначення, коли потрібно оновити позицію пікселя цифрового м'яча в лабіринті — щоб виглядало так, ніби він рухається відповідно до орієнтації плати.

Спочатку миттєве прискорення можна знайти за допомогою наступного:

pic

де g = 10.0

Далі, використовуючи дискретний крок часу, новий компонент швидкості знаходиться за допомогою:

pic

Звісно, не забувайте реалізувати логіку для обліку зіткнень з стінами лабіринту!

Далі зміну в переміщенні обчислюють за допомогою:

pic

Накопичене переміщення буде:

pic

Після цього кроку, якщо накопичене переміщення перевищить обраний пороговий значення, то центр цифрового м'яча має бути оновлений відповідно до знаку вектора переміщення. Це значення потрібно буде знову ініціалізувати в нуль.

Реалізація лабіринту та відображення

Реалізація вашого лабіринту повністю на ваш розсуд.

Наш метод передбачав використання бітмапу для позначення наявності стіни.

Ось деякі можливі конфігурації відображення. Зверніть увагу на верхній правий кут, де є таймер для того, щоб гравець встиг завершити лабіринт.

pic

Ігровий движок

Це повністю на ваш розсуд! Код доступний для натхнення. Будьте креативними!

Наш метод був реалізований послідовно, але ви можете використовувати RTOS, залежно від складності вашої гри.

Можливо, у вас буде кілька лабіринтів на вибір.

Динамік

Нарешті, динамік може відтворювати звук щоразу, коли гра завершується.

Аудіофайл — це великий одновимірний масив, що представляє різні рівні напруги, які він повинен вивести. В залежності від послідовності цих рівнів напруги генерується певна висота тону.

Ви також можете використовувати динамік для відтворення звуку зіткнення, коли м'яч вражає стіну.

Існує безліч способів бути креативним!

Сподіваюся, цей міні-урок дав вам хорошу ідею того, як створити вашу власну унікальну гру "М'яч у лабіринті". Бажаю успіху!

Перекладено з: How to Create a Fun Digital Ball-in-Maze Puzzle on an Embedded Device

Leave a Reply

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