If you are using Brick to express your Robot Physics in Yaml, Click adds the low latency communication you need to let your controller control your robots in the simulation like they were real robots. Click automatically finds your robots in a Brick scene and allows controller environments to send and receive signals without forcing your controller to depend on Brick. If you want receive updates on additional objects, you add a Click configuration to Brick, pointing to which objects should be communicated.
Click implements C++ and Python clients. Additional language support can be added using protobuf code generation tooling.
There are currently three main parts of click
- agxclick - a Simulation application using pclick, AGX and agxBrick that implements Click out of the box for a Brick model containing Robot(s).
- click - C++ click library with a democlient.
- pclick - Python click library with a demo client and demo server
The Click library implements creating, sending, receiving and interpreting messages across multiple platforms. Click can be used without agxclick, but the real benefit of Brick integration comes with agxclick.
The main idea behind click is to enable a non-Brick controller talking to a Brick enabled AGX Simulation in way configurable by Brick. The name comes from the sound two Bricks makes when connected.
There are three main considerations
- How the controller can send controls and receive sensor values in a similar fashion regardless of environment, ie real or sim.
- How Brick adds sensors or topology on top of urdf, and how this is communicated to the controller.
- How to communicate controls and sensors in an effective way.
The current solution is to introduce a Handshake, which enables the simulation to tell the controller what to expect in terms of how to control and what sensor data is being sent.
Messaging is peer to peer, where client and server take turn. Ie
- Client loops over send/recv
- Server loops over recv/send.
The messages are
Request | Response | Comment |
---|---|---|
HandshakeInitMessage | HandshakeMessage | |
SensorRequestMessage | SensorMessage | |
ControlMessage | SensorMessage | Client must also be prepared for ErrorMessage and ResetMessage |
ResetMessage | ResetMessage | Sending a ResetMessage will pause the simulation |
ErrorMessage | - | Sending an ErrorMessage will end the simulation |
A typical flow is
- Client controller connects and sends HandshakeInit
- Server responds with Handshake
- Client receives Handshake and validates the setup.
- [Optional step] Client sends SensorRequestMessage to get initial values
- [Optional step] Server responds with SensorMessage without starting simulation
- Client sends ControlMessage, this message will start the simulation
- Server responds with SensorMessage
- The loop 6-8 is repeated.
When the Client sends a ResetMessage, the Server
- will respond with ResetMessage
- will reset the simulation to the intial state
- will pause the simulation
- will not start the simulation until the first received ControlMessage, the client can send a SensorRequestMessage without starting simulation at this point.
The typical flow therefore is
- Client sends ResetMessage
- Server responds with ResetMessage
- [Optional] Client sends SensorRequestMessage
- [Optional] Server responds with SensorMessage without starting simulation
- Client sends ControlMessage
- Server sends SensorMessage
The same will happen when the Simulation is reset from simulation side, eg a user reset the simulation:
- Server responds with ResetMessage on any incoming Message (except ErrorMessage)
- [Optional] Client sends SensorRequestMessage
- [Optional] Server responds with SensorMessage without starting simulation
- Client sends ControlMessage
- Server sends SensorMessage
The HandshakeMessage contains both
- A Deprecated ControlType per scene
- The new ControlType per joint
Using ControlType per joint is preferred, but ControlType per scene is still supported but only when all joint input signals are the same type The server can always send ValueType.Multiple as ControlType, meaning client must check the Control Type of every joint. The server may (for backward compatibility) send ValueType.Angle, ValueType.AngularVelocity or ValueType.Torque1D if all joints have that same Control Type.
Also see ControlMessage below!
The ControlMessage contains mutually exclusive
- values - meaning each value may be of different type as specified in handshake
- angles (Deprecated) - meaning all values are Angle values as specified in handshake
- angularVelocities (Deprecated) - meaning all values are AngularVelocitiy1D values as specified in handshake
- torques (Deprecated) - meaning all values are Torque1D values as specified in handshake
The simulation is not started until after the first handshake is complete, ie when the first ControlMessage is received. After that, the simulation is stepped once per message, except after a ResetMessage; see above.
- Python, all platforms: Go to agxclick for python install instructions. If you only want click and not agxclick, then do:
pip install pclick
- Linux Ubuntu 20.04 C++ libraries and binaries (only available to registered users at git.algoryx.se for now):
wget --header "DEPLOY-TOKEN: <SECRET>" -O /tmp/click-shared-focal-amd64.deb "https://git.algoryx.se/api/v4/projects/algoryx%2Fexternal%2Fclick/packages/generic/click/0.4.1/click-shared-focal-amd64.deb"
apt-get install -yf /tmp/click-shared-focal-amd64.deb
- Windows C++ libraries and binaries (only available to registered users at git.algoryx.se for now)
Go to agxclick for brick model examples. After installing (or building from source as specified below), run these commands in separate prompts:
python3 -m pclick.demo.server
build/bin/democlient
This section and below are for developers developing Click
- C++ ControlMessage example
- C++ democlient
- C++ demoserver
- Python democlient
- Python demoserver
- Current protobuf schema
- Technology choices etc
NOTE: -DCMAKE_INSTALL_PREFIX=install makes install in build/install.
cmake -B oos -DCMAKE_BUILD_TYPE=Release -DCMAKE_GENERATOR=Ninja -DCMAKE_INSTALL_PREFIX=oos/install cpp-src
cd oos
ninja && ninja test install
or for shared library, add BUILD_SHARED_LIBS:
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_GENERATOR=Ninja -DCMAKE_INSTALL_PREFIX=oos/install -DBUILD_SHARED_LIBS=ON cpp-src
ninja click-tests && ninja test
will compile test dependencies and run tests in one step.
cmake -B oos -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=oos/install -G "Visual Studio 17 2022" -A x64 cpp-src
cmake --build oos --config Release --target INSTALL
cd oos
ctest
or for shared library, add BUILD_SHARED_LIBS:
cmake -B oos -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=oos/install -G "Visual Studio 17 2022" -A x64 cpp-src
cmake --build oos --config Release --target INSTALL
cd build
rm -rf * .github.conan.cmake
NOTE: Read agxclick to build and test agxclick
# Install click locally
pip3 install -e python-src
# Create virtual environment with requirements installed
cd python-src
poetry install
# Run tests
poetry run pytest
# Run demo server
poetry shell
python3 -m pclick.demo.server
The generated protobuf python code is committed in git repo. It is created as part of c++ build, but can be created by running protoc as below.
protoc -I=protobuf-src --python_out=python-src/src Messaging.proto
poetry build
We are using Catch2 testing framework with cmake integration
Python tests are using pytest
To circumvent clashes with python library click and pyClick, the python library is called pclick.
Releases are only done on git.algoryx.se, and tags are then pushed to github. They are made by pushing the tag to be released, GitLab will build, test and publish the version. Release tags are semver only, eg 0.1.2.
Steps:
- Update version in files below. Suggestion: Search and Replace old version for new.
- README.md
- agxclick/pyproject.toml
- agxclick/README.md
- agxclick/README-pypi.md
- cpp-src/CMakeLists.txt
- cpp-src/conanfile.py
- cpp-src/click/conan/CMakeLists.txt
- python-src/pyproject.toml
- Update releaselog.txt
- Push to branch and do MR
- When MR merged, create a tag in web IDE or tag from main and push, eg
git tag 0.4.1; git push origin 0.4.1
. - When built, binary artifacts:s are available in the Package Registry and python artifacts at pypi.org.
agxclick tests uses the generic Docker Image registry.algoryx.se/algoryx/external/agx-docker/agxbrick-minified:latest
.
Therefore when raising minimum required agxBrick version, agxBrick needs to be updated in the upstream as well in order for tests to run.