5: ROS 2 Version of Conway’s Game of Life in TypeScript

Implement Conway’s Game of Life using ROS 2 OccupancyMap and rviz2 for visualization.

As a fun project to help me get familiar with the ROS 2 OccupancyMap message, I coded up Conway’s Game of Life algorithm using an OccupancyMap to model the cellular automaton world. In this article I describe the high-level details of my Game of Life implementation.

The program is implemented using TypeScript and the Nodejs rclnodejs package. ROS 2 rviz2 is used to visualize the occupancy-maps published by the program. If you would like to jump straight to building and running my version, the source code is available here.

Game of Life Rules

Conway’s Game of Life, a.k.a., Life, is a cellular automaton developed by the mathematician, John Conway in 1970. Life consists of a 2D grid of cells, whith each cell having a state of alive or dead. A cell’s state may change from one generation to the next according to three simple rules.

  1. Any alive cell with two or three neighbors (adjacent cells) survives to the next generation.

2. Any dead cell with three neighbors becomes a live cell in the next generation.

3. All other live cells die in the next generation. Similarly, all other dead cells stay dead.

See the Resources section below for more info about Conway’s Game of Life.

OccupancyMap Message

I’ve already mentioned that the program uses the ROS 2 OccupancyMap for modeling the cellular world. Let’s take a look at the OccupancyMap definition which is defined as part of the nav_msgs package.

Note the info field of typeMapMetaData. MapMetaData (shown below) defines the grid dimensions on the data field as well as cell orientation and scale.

Project Details

The project will consist of the following:

  • ROS 2 node, named /ros2_js_examples/game_of_life
  • ROS 2 100x100 OccupancyMap will represent the cellular world
  • ROS 2 Timer will provide a tick every 500 milliseconds (2 Hz) that initiates the transition of the current world to the next generation
  • ROS 2 publisher will broadcast the updated OccupancyMap for each generation, topic = game_of_life
  • rviz2 will provide visualization of the cellular world
  • This program is implemented as a Nodejs application coded using TypeScript and the ROS 2 rclnodejs JavaScript client library.

Code

Create the project folder and change directory into it:

mkdir -p src/example4
cd src/example4

The project consists of 2 TypeScript files: index.ts and game-of-life.ts. To minimize redundant code narration I’ve tried to include liberal comments throughout the code as shown below.

Some key things to notice in the code:

  • The occupancy-map cell states are ALIVE = 100, DEAD = 0.
  • A ROS2 Timer is used rather than the more common setInterval() JavaScript function. This is because the ROS2 Timer is based on it’s parent node’s clock which can be configured to use simulated time and controlled externally.
  • To minimize memory the program uses only 2 data arrays: an array to hold the previous generation of cell states and an array to hold for the current generation of cell states. Also a single occupancy-map instance is created and updated on each new generation with the current generation of cell state data.

index.ts

game-of-life.ts

Build

From the project root folder run the TypeScript compiler. The output will appear in the dist/example4 folder.

tsc

Running game-of-life

Our game-of-life program runs in 2 processes that we will start individually.

First, launch the game-of-life node from a command shell:

node dist/example4/index.js

Once the program starts you should see messages dribble to stdout with information about the current generation number and number of alive cells.

Next run rviz2 to view the occupancy-maps published by the game-of-life node:

rviz2 -d src/example4/game-of-life.rviz

You should see an rviz2 window appear similar to the following:

If you need to reconfigure the rviz2 display or use ros2 CLI tools you will need the following information:

NODE_NAME = ‘game_of_life_node’;
NODE_NAMESPACE = ‘ros2_js_examples’;
TOPIC = ‘game_of_life’;
FRAME_ID = ‘game_of_life_frame’;

Wrap-up

I hope you’ve had fun developing your version of Conway’s Game of Life. You may consider additional improvements to your version such as parameterizing the occupancy-map size or using a predefined grid of cells rather than random cell states.

References

  1. Wikipedia — Conway’s Game of Life

2. Source code

Please consider liking this tutorial and following me here and on Twitter @ros2jsguy

“ROS 2 for JavaScript & TypeScript Developers” tutorials from a guy named Wayne