Реализуйте «Игру жизни» Конвея, используя ROS 2 OccupancyMap и rviz2 для визуализации.
В качестве забавного проекта, который поможет мне познакомиться с сообщением ROS 2 OccupancyMap, я закодировал алгоритм Конвея Game of Life, используя OccupancyMap для моделирования мира клеточных автоматов. В этой статье я описываю высокоуровневые детали моей реализации Game of Life.
Программа реализована с использованием TypeScript и пакета Nodejs rclnodejs. ROS 2 rviz2
используется для визуализации карт занятости, опубликованных программой. Если вы хотите сразу перейти к сборке и запуску моей версии, исходный код доступен здесь.
Правила игры «Жизнь»
Игра Конвея «Жизнь», также известная как «Жизнь», представляет собой клеточный автомат, разработанный математиком Джоном Конвеем в 1970 году. Жизнь состоит из двумерной сетки ячеек, каждая из которых имеет состояние «живая» или «мертвая». Состояние клетки может меняться от поколения к поколению в соответствии с тремя простыми правилами.
- Любая живая клетка с двумя-тремя соседями (соседними клетками) доживает до следующего поколения.
2. Любая мертвая клетка с тремя соседями становится живой клеткой в следующем поколении.
3. Все остальные живые клетки погибают в следующем поколении. Точно так же все другие мертвые клетки остаются мертвыми.
Дополнительную информацию об игре Conway's Game of Life см. в разделе Ресурсы ниже.
Сообщение OccupancyMap
Я уже упоминал, что программа использует ROS 2 OccupancyMap для моделирования сотового мира. Давайте взглянем на определение OccupancyMap, которое определено как часть пакета nav_msgs
.
Обратите внимание на поле info
типаMapMetaData
. MapMetaData (показан ниже) определяет размеры сетки в поле data
, а также ориентацию и масштаб ячеек.
Подробности проекта
Проект будет состоять из следующего:
- Узел ROS 2 с именем
/ros2_js_examples/game_of_life
- ROS 2 100x100 OccupancyMap представит мир сотовой связи
- Таймер ROS 2 будет обеспечивать тик каждые 500 миллисекунд (2 Гц), который инициирует переход текущего мира к следующему поколению.
- Издатель ROS 2 будет транслировать обновленную OccupancyMap для каждого поколения, тема =
game_of_life
- rviz2 обеспечит визуализацию сотового мира
- Эта программа реализована в виде приложения Nodejs, закодированного с использованием TypeScript и клиентской библиотеки ROS 2 rclnodejs JavaScript.
Код
Создайте папку проекта и перейдите в нее:
mkdir -p src/example4 cd src/example4
Проект состоит из 2 файлов TypeScript: index.ts и game-of-life.ts. Чтобы свести к минимуму избыточное повествование кода, я попытался включить либеральные комментарии по всему коду, как показано ниже.
Некоторые ключевые моменты, на которые стоит обратить внимание в коде:
- Состояния ячеек карты занятости: ALIVE = 100, DEAD = 0.
- Вместо более распространенной функции JavaScript setInterval() используется таймер ROS2. Это связано с тем, что таймер ROS2 основан на часах родительского узла, которые можно настроить для использования смоделированного времени и внешнего управления.
- Для минимизации памяти программа использует только 2 массива данных: массив для хранения состояний ячеек предыдущего поколения и массив для хранения состояний ячеек текущего поколения. Также создается один экземпляр карты занятости и обновляется в каждом новом поколении текущим поколением данных о состоянии ячейки.
index.ts
игра-жизни.ts
Строить
Из корневой папки проекта запустите компилятор TypeScript. Результат появится в папке dist/example4
.
tsc
Игра в жизнь
Наша программа «игра в жизнь» состоит из 2 процессов, которые мы будем запускать по отдельности.
Сначала запустите узел игры из командной оболочки:
node dist/example4/index.js
После запуска программы на стандартный вывод должны выводиться сообщения с информацией о текущем номере поколения и количестве живых клеток.
Затем запустите rviz2
, чтобы просмотреть карты занятости, опубликованные узлом игры-жизни:
rviz2 -d src/example4/game-of-life.rviz
Вы должны увидеть окно rviz2, похожее на следующее:
Если вам нужно перенастроить rviz2
дисплей или использовать инструменты ros2
CLI, вам потребуется следующая информация:
NODE_NAME = ‘game_of_life_node’; NODE_NAMESPACE = ‘ros2_js_examples’; TOPIC = ‘game_of_life’; FRAME_ID = ‘game_of_life_frame’;
Заворачивать
Надеюсь, вы получили удовольствие от разработки своей версии «Игры жизни» Конвея. Вы можете рассмотреть дополнительные улучшения вашей версии, такие как параметризация размера карты занятости или использование предопределенной сетки ячеек, а не случайных состояний ячеек.
использованная литература
2. Исходный код
Пожалуйста, поставьте лайк этому руководству и подпишитесь на меня здесь и в Твиттере @ros2jsguy