Skip to content



Python is main language of project. So, students may learn control theory and make experiments faster and easier. Firstly, you need checkout repo and prepare enviroment.

git clone

We have a built container with all dependencies, use it for development and testing (you need to have docker and docker-compose installed). Run in root of repo following commands.

Pull latest actual image docker compose pull, that you may start devcontainer in VSCode or run it manually.

# enter to container
docker exec -it cartpole bash

Repo folder is mounted as /cartpole dir, so you can edit files in your favorite IDE. We highly recommend to use VS Code, since we provide everything for comfortable development. After you set up your environment, you can run tests to check that everything is OK.

pytest tests

Also there are some environment variables, which may be useful for you:

  • $CONTAINER_NAME - name of container (default is cartpole)

If you want to use your own python environment, you can install all dependencies manually, using poetry.

# check poetry config
poetry config --list 

# install all depencies to .venv folder
poetry install

# run tests to check that everithing is OK
poetry run pytest tests


For visualization of real time data we use foxglove studio. We strongly suggest to use our instance, but you may also setup server with our specific fixes by yourself (more information here). In Foxglove Studio select Open connection than Foxglove WebSocket and enter ws://localhost:8765 (use your port) in address field.


We have convinient logging system, it may show data in real time and replay saved data in mcap format.

import cartpole.log as log

from pydantic import BaseModel

import random
import time

# all messages must be inherited from BaseModel
class RandMsg(BaseModel):
    dist: str = 'uniform(0, 1)'
    value: float = 0.0

# define log file name
log.setup(log_path='log_example.mcap', level=log.DEBUG)

# messages are available in real time in foxglove (websocket mode)
for i in range(10):
    value = random.uniform(0, 1)

    # publish message, timestamp is optional (default is current time)
    log.publish('/random', RandMsg(value=value))

    # print message to console and log (see /log topic)'publish {value:.2f}')

    # add some delay for demo purposes


For development and testing of control algorithms, we provide CartPole simulator, which fully implemntet CartPoleBase interface. The simulation is carried out by numerical integration of parameterized dynamic system (more information here). Also simulator may be used to train ML agents.

from cartpole import Error, State
from cartpole import Simulator
from cartpole import log

import time

# set simulation step as 0.05 seconds
delta = 0.05

# setup logging (look at mcap logs after simulation)

# create simulator with default config
cartpole = Simulator()

# reset simulator to initial state
cartpole.reset(state=State(cart_position=0, pole_angle=2))

# run simulation
for _ in range(1000):
    # use for loggin simulation time instead of real time
    state = cartpole.get_state()

    # log system state and simulator info
    log.publish('/cartpole/state', state, state.stamp)

    # make simulation step


You can build and run docs server locally.

mkdocs serve -a