diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 815c00e5b4..a1c265f3fb 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -11,12 +11,16 @@ concurrency:
cancel-in-progress: true
jobs:
- ubuntu22-tests:
- name: Ubuntu 22.04 Build
- runs-on: ubuntu-22.04
+ multiplatform-build:
+ strategy:
+ matrix:
+ platform: [ ubuntu-22.04, ubuntu-24.04 ]
+
+ name: Ubuntu Alternate Builds
+ runs-on: ${{ matrix.platform }}
steps:
# checks-out the repository under $GITHUB_WORKSPACE
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Environment Setup
run: |
@@ -25,24 +29,31 @@ jobs:
- name: Software Build Test
run: |
cd src
- bazel build --show_timestamps \
- -- //... -//software:unix_full_system \
- -//software/simulated_tests/... \
- -//software/ai/hl/... \
- -//software/field_tests/... \
- -//software/jetson_nano/... \
+ bazel build --show_timestamps --copt=-O3 \
+ -- //... -//software:unix_full_system \
+ -//software/simulated_tests/... \
+ -//software/ai/hl/... \
+ -//software/field_tests/... \
+ -//software/embedded/... \
+ -//cc_toolchain/...
- name: Jetson Nano Build Test
run: |
cd src
- bazel build --cpu=jetson_nano //software/jetson_nano:thunderloop_main --copt=-O3
+ bazel build //software/embedded:thunderloop_main --copt=-O3 --//software/embedded:host_platform=NANO --platforms=//cc_toolchain:robot
+
+ - name: Raspberry Pi Build Test
+ run: |
+ cd src
+ bazel build //software/embedded:thunderloop_main --copt=-O3 --//software/embedded:host_platform=PI --platforms=//cc_toolchain:robot
+
software-tests:
name: Software Tests
runs-on: ubuntu-20.04
steps:
# checks-out the repository under $GITHUB_WORKSPACE
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Environment Setup
run: |
@@ -56,14 +67,15 @@ jobs:
-//software/simulated_tests/... \
-//software/ai/hl/... \
-//software/field_tests/... \
- -//software/ai/navigator/...
+ -//software/ai/navigator/... \
+ -//cc_toolchain/...
- jetson-nano-tests:
- name: Jetson Nano Software Tests
+ robot-tests:
+ name: Robot Software Tests
runs-on: ubuntu-20.04
steps:
# checks-out the repository under $GITHUB_WORKSPACE
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Environment Setup
run: |
@@ -85,14 +97,21 @@ jobs:
- name: Jetson Nano Build
run: |
cd src
- bazel build --cpu=jetson_nano //software/jetson_nano:thunderloop_main --copt=-O3
+ bazel build //software/embedded:thunderloop_main --copt=-O3 --//software/embedded:host_platform=NANO --platforms=//cc_toolchain:robot
+
+
+ - name: Raspberry Pi Build
+ run: |
+ cd src
+ bazel build //software/embedded:thunderloop_main --copt=-O3 --//software/embedded:host_platform=PI --platforms=//cc_toolchain:robot
+
simulated-gameplay-tests:
name: Simulated Gameplay Tests
runs-on: ubuntu-20.04
steps:
# checks-out the repository under $GITHUB_WORKSPACE
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Environment Setup
run: |
@@ -102,35 +121,35 @@ jobs:
run: |
cd src
bazel test --copt=-O3 --flaky_test_attempts=3 --show_timestamps \
- //software:unix_full_system \
- //software/simulated_tests/... \
- //software/ai/hl/... \
+ //software:unix_full_system \
+ //software/simulated_tests/... \
+ //software/ai/hl/... \
//software/ai/navigator/...
- name: Upload simulated test proto logs
# Ensure that simulated test logs get uploaded
if: always()
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
- name: blue-ai-proto-logs
+ name: blue-sim-test-proto-logs
path: |
- /tmp/tbots/blue/logs
+ /tmp/tbots/blue/test/*/proto_*
- name: Upload simulated test proto logs
# Ensure that simulated test logs get uploaded
if: always()
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
- name: yellow-ai-proto-logs
+ name: yellow-sim-test-proto-logs
path: |
- /tmp/tbots/yellow/logs
+ /tmp/tbots/yellow/test/*/proto_*
autorefd-game:
name: AutoRef'd Game (3 Minutes)
runs-on: ubuntu-20.04
steps:
# checks-out the repository under $GITHUB_WORKSPACE
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Environment Setup
run: |
@@ -144,7 +163,7 @@ jobs:
- name: Upload AI vs AI logs
# Ensure that simulated test logs get uploaded
if: always()
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: blue-ai-vs-ai-proto-logs
path: |
@@ -153,7 +172,7 @@ jobs:
- name: Upload AI vs AI logs
# Ensure that simulated test logs get uploaded
if: always()
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: yellow-ai-vs-ai-proto-logs
path: |
diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml
index fc14faa4db..bcffc1dc83 100644
--- a/.github/workflows/pre-commit.yml
+++ b/.github/workflows/pre-commit.yml
@@ -18,7 +18,7 @@ jobs:
if: github.event.pull_request.draft == false
steps:
# checks-out the repository under $GITHUB_WORKSPACE
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Environment Setup
run: |
diff --git a/docs/fsm-diagrams.md b/docs/fsm-diagrams.md
index be8fd153c5..7dbe3e5538 100644
--- a/docs/fsm-diagrams.md
+++ b/docs/fsm-diagrams.md
@@ -314,6 +314,21 @@ Terminate:::terminate --> Terminate:::terminate
```
+## [HaltFSM](/src/software/ai/hl/stp/tactic/halt/halt_fsm.h)
+
+```mermaid
+
+stateDiagram-v2
+classDef terminate fill:white,color:black,font-weight:bold
+direction LR
+[*] --> StopState
+StopState --> StopState : [!stopDone]\nupdateStop
+StopState --> Terminate:::terminate : [stopDone]\nupdateStop
+Terminate:::terminate --> StopState : [!stopDone]\nupdateStop
+Terminate:::terminate --> Terminate:::terminate : [stopDone]\nupdateStop
+
+```
+
## [KickFSM](/src/software/ai/hl/stp/tactic/kick/kick_fsm.h)
```mermaid
@@ -441,18 +456,3 @@ Terminate:::terminate --> Terminate:::terminate : SET_STOP_PRIMITIVE_ACTION
```
-## [StopFSM](/src/software/ai/hl/stp/tactic/stop/stop_fsm.h)
-
-```mermaid
-
-stateDiagram-v2
-classDef terminate fill:white,color:black,font-weight:bold
-direction LR
-[*] --> StopState
-StopState --> StopState : [!stopDone]\nupdateStop
-StopState --> Terminate:::terminate : [stopDone]\nupdateStop
-Terminate:::terminate --> StopState : [!stopDone]\nupdateStop
-Terminate:::terminate --> Terminate:::terminate : [stopDone]\nupdateStop
-
-```
-
diff --git a/docs/getting-started-wsl.md b/docs/getting-started-wsl.md
index 999f86e7b8..1e48c769b8 100644
--- a/docs/getting-started-wsl.md
+++ b/docs/getting-started-wsl.md
@@ -39,7 +39,7 @@ If you are not using Windows 11 and would prefer not to upgrade, you can follow
3. Now, let's install Ubuntu.
- Download the WSL2 kernel from [here](https://docs.microsoft.com/en-us/windows/wsl/wsl2-kernel).
- Open a PowerShell window and run command `wsl --set-default-version 2` to use WSL2 by default.
- - Install Ubuntu 20.04 LTS or Ubuntu 22.04 LTS from the Microsoft Store.
+ - Install Ubuntu 20.04 LTS, Ubuntu 22.04 LTS or Ubuntu 24.04 LTS from the Microsoft Store.
- Open the Ubuntu app in the Start menu. It will open a command prompt and ask you to create a new UNIX username and password for your WSL2 Ubuntu installation.
### X Server Setup
diff --git a/docs/getting-started.md b/docs/getting-started.md
index c9aea63a5a..4c6d3bbd54 100644
--- a/docs/getting-started.md
+++ b/docs/getting-started.md
@@ -1,10 +1,5 @@
-Table of Contents
-=================
-
+Table of Contents
+=================
* [Software Setup](#software-setup)
* [Introduction](#introduction)
@@ -30,8 +25,8 @@ Table of Contents
* [Profiling](#profiling)
* [Callgrind](#callgrind)
* [Tracy](#tracy)
- * [Building for Jetson Nano](#building-for-jetson-nano)
- * [Deploying to Jetson Nano](#deploying-to-jetson-nano)
+ * [Building for the robot](#building-for-the-robot)
+ * [Deploying Robot Software to the robot](#deploying-robot-software-to-the-robot)
* [Setting up Virtual Robocup 2021](#setting-up-virtual-robocup-2021)
* [Setting up the SSL Simulation Environment](#setting-up-the-ssl-simulation-environment)
* [Pushing a Dockerfile to dockerhub](#pushing-a-dockerfile-to-dockerhub)
@@ -49,6 +44,14 @@ Table of Contents
* [Example Workflow](#example-workflow)
* [Testing](#testing)
+
+
# Software Setup
## Introduction
@@ -63,9 +66,15 @@ These instructions assume you have a basic understanding of Linux and the comman
### Operating systems
-We currently only support Linux, specifically Ubuntu 20.04 LTS and Ubuntu 22.04 LTS. You are welcome to use a different version or distribution of Linux, but may need to make some tweaks in order for things to work.
+We currently only support Linux, specifically Ubuntu.
+
+If you have a X86_64 machine, we support Ubuntu 20.04 LTS, Ubuntu 22.04 LTS and Ubuntu 24.04 LTS.
-You can use Ubuntu 20.04 LTS and Ubuntu 22.04 LTS inside Windows through Windows Subsystem for Linux, by following [this guide](./getting-started-wsl.md). **Running and developing Thunderbots on Windows is experimental and not officially supported.**
+If you have a ARM64 (also known as AARCH64) machine, we support Ubuntu 24.04 LTS.
+
+You are welcome to use a different version or distribution of Linux, but may need to make some tweaks in order for things to work.
+
+You can use Ubuntu 20.04 LTS, Ubuntu 22.04 LTS or Ubuntu 24.04 LTS inside Windows through Windows Subsystem for Linux, by following [this guide](./getting-started-wsl.md). **Running and developing Thunderbots on Windows is experimental and not officially supported.**
### Getting the Code
@@ -339,17 +348,19 @@ Tracy also samples call stacks. If the profiled binary is run with root permissi
./tbots.py run thunderscope_main --tracy --sudo
-## Building for Jetson Nano
+## Building for the robot
-To build for the Jetson Nano, build the target with the `--cpu=jetson_nano` flag and the toolchain will automatically build using the ARM toolchain for Jetson Nano. For example, `bazel build --cpu=jetson_nano //software/geom/...`.
+To build for the robot computer, build the target with the `--platforms=//cc_toolchain:robot` flag and the toolchain will automatically build using the ARM toolchain. For example, `bazel build --platforms=//cc_toolchain:robot //software/geom/...`.
-## Deploying to Jetson Nano
+## Deploying Robot Software to the robot
-We use ansible to automatically update software running on the Jetson Nano. [More info here.](useful-robot-commands.md#flashing-the-nano)
+We use Ansible to automatically update software running on the robot. [More info here.](useful-robot-commands.md#flashing-the-robots-compute-module)
To update binaries on a working robot, you can run:
-`bazel run //software/jetson_nano/ansible:run_ansible --cpu=jetson_nano -- --playbook deploy_nano.yml --hosts --ssh_pass `
+`bazel run //software/embedded/ansible:run_ansible --platforms=//cc_toolchain:robot --//software/embedded:host_platform= -- --playbook deploy_robot_software.yml --hosts --ssh_pass `
+
+Where `` is the robot platform you are deploying to (`PI` or `NANO`), and `` is the IP address of the robot you are deploying to. The `robot_password` is the password used to login to the `robot` user on the robot.
## Setting up Virtual Robocup 2021
diff --git a/docs/robot-software-architecture.md b/docs/robot-software-architecture.md
index 8bd11d84d7..9f6059524b 100644
--- a/docs/robot-software-architecture.md
+++ b/docs/robot-software-architecture.md
@@ -16,11 +16,14 @@
## Ansible
-[Ansible](https://www.ansible.com/overview/how-ansible-works) allows us to run actions on multiple robots at once. Actions are communicated through YAML files called playbooks. Playbooks contain a series of tasks (ex move a file, run this script, output this command) and logic dictating dependencies between tasks. When playbooks are run, Ansible establishes an SSH connection between the user's computer and target Jetson Nanos, allowing it to run the tasks in the playbook. Output from each task, and any other requested output, is displayed on the console
+[Ansible](https://www.ansible.com/overview/how-ansible-works) allows us to run actions on multiple robots at once. Actions are communicated through YAML files called playbooks. Playbooks contain a series of tasks (eg. move a file, run this script, output this command) and logic dictating dependencies between tasks. When playbooks are run, Ansible establishes an SSH connection between the user's computer and robot, allowing it to run the tasks in the playbook. Output from each task, and any other requested output, is displayed on the console
For a more detailed look at how Ansible works, [see the RFC](https://docs.google.com/document/d/1hN3Us2Vjr8z6ihqUVp_3L7rrjKc-EZ-l2hZJc31gNOc/edit)
-Example command: `bazel run //software/jetson_nano/ansible:run_ansible --cpu=jetson_nano -- --playbook deploy_nano.yml --hosts --ssh_pass `
+Example command: `bazel run //software/embedded/ansible:run_ansible --platforms=//cc_toolchain:robot --//software/embedded:host_platform= -- --playbook deploy_robot_software.yml --hosts --ssh_pass `
+* : `PI` or `NANO` depending on the computer on the robot
+* : IP address of the robot
+* : Password of the robot
More commands available [here](useful-robot-commands.md#off-robot-commands)
@@ -36,14 +39,6 @@ To learn more about how it works, [see the RFC](https://docs.google.com/document
# Thunderloop
-Thunderloop is software that runs in a loop. It continuously polls services (unrelated from Systemd) sending relevant control proto (`PowerControl`, `MotorControl`) and receiving back status proto. Currently we have a [Network](https://github.com/UBC-Thunderbots/Software/blob/master/src/software/jetson_nano/services/network/network.cpp), [Power](https://github.com/UBC-Thunderbots/Software/blob/master/src/software/jetson_nano/services/power.cpp) and [Motor service](https://github.com/UBC-Thunderbots/Software/blob/master/src/software/jetson_nano/services/motor.cpp). Thunderloop also receives `World` and `PrimitiveSet` Proto from AI and sends back Robot Status.
+Thunderloop is software that runs in a loop. It continuously polls services (unrelated from Systemd), sending relevant control protos (`PowerControl`, `MotorControl`) and receiving back status protos from the power and motor boards. Currently we have a [Network](https://github.com/UBC-Thunderbots/Software/blob/master/src/software/embedded/services/network/network.cpp), [Power](https://github.com/UBC-Thunderbots/Software/blob/master/src/software/embedded/services/power.cpp) and [Motor](https://github.com/UBC-Thunderbots/Software/blob/master/src/software/embedded/services/motor.cpp) services. Thunderloop also receives `World` and `PrimitiveSet` protos from AI and sends back `Robot Status` protos.
-Motor and Power service both interface with their respective electrical boards over different communication interfaces, namely SPI and UART respectively.
-
-# Announcements
-
-Broadcasts packets for what robot IDs are connected to wifi and what IPs they have. Combined with `robot_broadcast_receiver.py` allows us to see all robots on the network.
-
-# Display
-
-Displays information about the robot for us. Uses redis to receive info from other processes. Can also change values with physical buttons.
+Motor and Power services both interface with their respective electrical boards over different communication interfaces, namely SPI and UART respectively.
diff --git a/docs/useful-robot-commands.md b/docs/useful-robot-commands.md
index e5399fa8d6..431f7c3c45 100644
--- a/docs/useful-robot-commands.md
+++ b/docs/useful-robot-commands.md
@@ -1,32 +1,40 @@
-# Common Robot Commands
+Table of Contents
+=================
-# Table of Contents
+* [Table of Contents](#table-of-contents)
* [Common Debugging Steps](#common-debugging-steps)
* [Off Robot Commands](#off-robot-commands)
* [Wifi Disclaimer](#wifi-disclaimer)
- * [Miscellaneous Ansible Tasks & Options](#miscellaneous-ansible-tasks--options)
- * [Flashing the nano](#flashing-the-nano)
+ * [Miscellaneous Ansible Tasks & Options](#miscellaneous-ansible-tasks--options)
+ * [Flashing the robot's compute module](#flashing-the-robots-compute-module)
* [Flashing the powerboard](#flashing-the-powerboard)
- * [Setting up nano](#setting-up-nano)
+ * [Setting up the embedded host](#setting-up-the-embedded-host)
+ * [Jetson Nano](#jetson-nano)
+ * [Raspberry Pi](#raspberry-pi)
* [Robot Diagnostics](#robot-diagnostics)
+ * [For Just Diagnostics](#for-just-diagnostics)
+ * [For AI + Diagnostics](#for-ai--diagnostics)
* [Robot Auto Test](#robot-auto-test)
* [On Robot Commands](#on-robot-commands)
* [Systemd Services](#systemd-services)
* [Debugging Uart](#debugging-uart)
* [Redis](#redis)
+
+
+
# Common Debugging Steps
```mermaid
---
title: Robot Debugging Steps
---
flowchart TD
- ssh(Can you SSH into the robot?
- `ssh robot@192.168.0.20RobotID` OR `ssh robot@robot_name.local`
- E.g. `ssh robot@192.168.0.203` or `ssh robot@robert.local`
- for a robot called robert with robot id 3)
+ ssh("Can you SSH into the robot?
+ `ssh robot@192.168.0.20RobotID` (for Nanos) OR `ssh robot@192.168.5.20RobotID` (for Pis) OR `ssh robot@robot_name.local`
+ e.g. `ssh robot@192.168.0.203` (for Nanos) or `ssh robot@192.168.5.203` (for Pis) or `ssh robot@robert.local`
+ for a robot called robert with robot id 3")
ssh ---> |Yes| tloop_status
- ssh --> |No - Second Try| monitor("`Connect Jetson to an external monitor and check wifi connection _or_ SSH using an ethernet cable`")
+ ssh --> |No - Second Try| monitor("Connect Jetson or Pi to an external monitor and check wifi connection or SSH using an ethernet cable")
ssh --> |No - First Try| restart(Restart robot)
restart --> ssh
@@ -53,12 +61,12 @@ flowchart TD
`service thunderloop restart`)
tloop_status --> |Running| tloop_logs(Check Thunderloop logs for errors
`journalctl -fu thunderloop -n 300`)
- tloop_logs --> |No Errors| check_redis(Does `redis-cli get /network_interface` return 'wlan0',
+ tloop_logs --> |No Errors| check_redis(Does `redis-cli get /network_interface` return 'wlan0' or 'tbots',
and does `redis-cli get /channel_id` return '0'?)
- tloop_logs --> |Contains Errors| rip2("`Fix errors or check errors with a lead`")
- check_redis --> |No| update_redis(Update Redis constants by running:
- `redis-cli set /network_interface 'wlan0'`
- `redis-cli set /channel_id '0'`)
+ tloop_logs --> |Contains Errors| rip2("Fix errors or check errors with a lead")
+ check_redis --> |No| update_redis("Update Redis constants by running:
+ `redis-cli set /network_interface 'wlan0'` (for Nanos) OR `redis-cli set /network_interface 'tbots'` (for Pis)
+ `redis-cli set /channel_id '0'`")
check_redis --> |Yes| rip3(Check with a lead)
update_redis --> tloop_restart
tloop_restart --> tloop_status
@@ -78,14 +86,14 @@ The IP address of the robots on the tbots network is `192.168.0.20` so
Individual miscellaneous tasks (ex reboot, shutdown, rtt test) can be run through the `misc.yml` playbook by specifying the corresponding tag.
-To view a list of supported arguments, run
-`bazel run //software/jetson_nano/ansible:run_ansible --cpu=jetson_nano -- -h`
+To view a list of supported arguments, run:
+`bazel run //software/embedded/ansible:run_ansible --platforms=//cc_toolchain:robot -h`
If desired, the `-ho`, `--hosts` argument can be replaced with `-p`, `--port`, defining a port to listen to for Announcements from hosts.
The `--tags` argument can be used to specify which actions to perform and on which services.
-## Flashing the nano
+## Flashing the robot's compute module
This will stop the current Systemd services, replace and restart them. Binaries that are used for Systemd services are located in a folder in `home/robot` (the default directory) called `thunderbots_binaries`.
@@ -93,31 +101,43 @@ This will stop the current Systemd services, replace and restart them. Binaries
This will trigger motor calibration meaning the wheels may spin. Please elevate the robot so the wheels are not touching the ground for proper calibration.
-`bazel run //software/jetson_nano/ansible:run_ansible --cpu=jetson_nano -- --playbook deploy_nano.yml --hosts --ssh_pass `
+`bazel run //software/embedded/ansible:run_ansible --platforms=//cc_toolchain:robot --//software/embedded:host_platform= -- --playbook deploy_robot_software.yml --hosts --ssh_pass `
+* \ is the host platform on the robot (either `PI` or `NANO`)
+* is the IP address of the robot
+* is the password of the `robot` user account
-You could also use the `tbots.py` script to flash
+You could also use the `tbots.py` script to flash robot software
-`./tbots.py run run_ansible -f -pwd ` (Note that this uses robot IDs rather than full robot IP addresses)
+`./tbots.py run run_ansible -pl -f -pwd ` (Note that this uses robot IDs rather than full robot IP addresses)
+* \ is the host platform on the robot (either `PI` or `NANO`
+* is a list of robot IDs to flash
+* is the password of the `robot` user account
-Example: Flashing robots 1, 4, and 7
+Example: Flashing robots 1, 4, and 7 that have a Raspberry Pi
-`./tbots.py run run_ansible -f 1 4 7 -pwd `
+`./tbots.py run run_ansible -pl PI -f 1 4 7 -pwd `
## Flashing the powerboard
-This will flash powerloop, the current firmware in `software/power/`, onto the power board. It will prompt the user into setting the powerboard into bootloader mode by holding the boot button (left if looking from the back of the robot) and pressing the reset button (right if looking from the back of the robot), then releasing the reset button first, then the boot button. Once the board is flashed, pressing the reset button after to use the new firmware.
+This will flash powerloop, the current firmware in `software/power/`, onto the power board. It will prompt the user into setting the powerboard into bootloader mode by holding the boot button (left if looking from the back of the robot) and pressing the reset button (right if looking from the back of the robot), then releasing the reset button first, then the boot button. Once the board is flashed, pressing the reset button after to use the new firmware.
Looking from the back of the robot the reset and boot buttons are on right side of the battery holder on the lowest board with the reset being on the left and the boot on the right. Warning it may kick/chip when pressed.
-`bazel run //software/jetson_nano/ansible:run_ansible --cpu=jetson_nano -- --playbook deploy_powerboard.yml --hosts --ssh_pass `
+`bazel run //software/embedded/ansible:run_ansible --platforms=//cc_toolchain:robot -- --playbook deploy_powerboard.yml --hosts --ssh_pass `
+
+## Setting up the embedded host
+
+This section refers to setting up the computer on the robot for the first time. We need to setup dependencies, drivers and necessary configurations.
+
+Setting up the robot for the first time requires internet access
-## Setting up nano
+### Jetson Nano
-This refers to setting up the Jetson Nano for the first time. This will enable Systemd services, modify device tree files and perform other setup necessary for the communication protocols used.
+`bazel run //software/embedded/ansible:run_ansible --platforms=//cc_toolchain:robot --//software/embedded:host_platform=NANO -- --playbook setup_nano.yml --hosts --ssh_pass `
-Setting up the nano for the first time requires internet access
+### Raspberry Pi
-`bazel run //software/jetson_nano/ansible:run_ansible --cpu=jetson_nano -- --playbook setup_nano.yml --hosts --ssh_pass `
+`bazel run //software/embedded/ansible:run_ansible --platforms=//cc_toolchain:robot --//software/embedded:host_platform=PI -- --playbook setup_raspberry_pi.yml --hosts --ssh_pass `
## Robot Diagnostics
@@ -125,13 +145,13 @@ Robot Diagnostics allow users to input various commands to the robots. It can be
If multiple people are using robot diagnostics at the same time on the same network please make sure each person only connects to the robots they are testing via the checkboxes
-###For Just Diagnostics
+### For Just Diagnostics
From Software/src
`./tbots.py run thunderscope --run_diagnostics --interface `
-###For AI + Diagnostics
+### For AI + Diagnostics
From Software/src
@@ -144,9 +164,10 @@ Runs the robot auto test fixture on a robot through Ansible, which tests the mot
From Software/src:
-`bazel run //software/jetson_nano/ansible:run_ansible --cpu=jetson_nano -- --playbook robot_auto_test_playbook.yml --hosts --ssh_pass `
-* replace the with the actual ip address of the jetson nano for the ssh connection.
-* replace the with the actual password for the jetson nano for the ssh connection.
+`bazel run //software/embedded/ansible:run_ansible --//software/embedded:host_platform= --platforms=//cc_toolchain:robot -- --playbook robot_auto_test_playbook.yml --hosts --ssh_pass `
+* replace the \ with the target platform for the robot (either `PI` or `NANO`)
+* replace the \ with the actual ip address of the jetson nano for the ssh connection.
+* replace the with the actual password for the jetson nano for the ssh connection.
# On Robot Commands
diff --git a/environment_setup/setup_software.sh b/environment_setup/setup_software.sh
index d9531f5173..422439bb77 100755
--- a/environment_setup/setup_software.sh
+++ b/environment_setup/setup_software.sh
@@ -11,12 +11,6 @@
# unit tests
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
-print_status_msg () {
- echo "================================================================"
- echo $1
- echo "================================================================"
-}
-
# Save the parent dir of this so we can always run commands relative to the
# location of this script, no matter where it is called from. This
# helps prevent bugs and odd behaviour if this script is run through a symlink
@@ -24,6 +18,11 @@ print_status_msg () {
CURR_DIR=$(dirname -- "$(readlink -f -- "$BASH_SOURCE")")
cd "$CURR_DIR" || exit
+source util.sh
+
+arch=$(uname -m)
+print_status_msg "Detected architecture: ${arch}"
+
print_status_msg "Installing Utilities and Dependencies"
sudo apt-get update
@@ -49,10 +48,10 @@ host_software_packages=(
codespell # Fixes typos
curl
default-jdk # Needed for Bazel to run properly
- gcc-9 # We use gcc 9.3.0
+ gcc-10 # Full system compiles with gcc 10
libstdc++6-9-dbg
git # required for build
- g++-9
+ g++-10
kcachegrind # This lets us view the profiles output by callgrind
libeigen3-dev # A math / numerical library used for things like linear regression
libprotobuf-dev
@@ -62,9 +61,9 @@ host_software_packages=(
protobuf-compiler # This is required for the "NanoPb" library, which does not
# properly manage this as a bazel dependency, so we have
# to manually install it ourselves
- python3.10 # Python 3
- python3.10-dev # Python 3 headers
- python3.10-venv # Virtual Environment
+ python3.12 # Python 3
+ python3.12-dev # Python 3 headers
+ python3.12-venv # Virtual Environment
python3-pip # Required for bazel to install python dependencies for build targets
python3-protobuf # This is required for the "NanoPb" library, which does not
# properly manage this as a bazel dependency, so we have
@@ -90,17 +89,27 @@ if [[ $(lsb_release -rs) == "20.04" ]]; then
host_software_packages+=(llvm-6.0)
host_software_packages+=(libclang-6.0-dev)
host_software_packages+=(libncurses5)
- host_software_packages+=(qt5-default)
# This fixes missing headers by notifying the linker
- ldconfig
+ sudo ldconfig
fi
-if [[ $(lsb_release -rs) == "22.04" ]]; then
- host_software_packages+=(qtbase5-dev)
+# Clear the download cache
+rm -rf /tmp/tbots_download_cache
+mkdir /tmp/tbots_download_cache
+
+if [[ $(lsb_release -rs) == "22.04" ]] || [[ $(lsb_release -rs) == "24.04" ]]; then
+ # This is required because a Braille TTY device that Linux provides a driver for conflicts with the ESP32
+ wget -nc https://github.com/UBC-Thunderbots/Software-External-Dependencies/blob/main/85-brltty.rules -O /tmp/tbots_download_cache/85-brltty.rules
+ sudo mv /tmp/tbots_download_cache/85-brltty.rules /usr/lib/udev/rules.d/85-brltty.rules
+fi
- wget -nc https://github.com/UBC-Thunderbots/Software-External-Dependencies/blob/main/85-brltty.rules -O /tmp/85-brltty.rules
- sudo mv /tmp/85-brltty.rules /usr/lib/udev/rules.d/85-brltty.rules
+virtualenv_opt_args=""
+if [[ $(lsb_release -rs) == "24.04" ]]; then
+ host_software_packages+=(python3-pyqt6)
+ host_software_packages+=(pyqt6-dev-tools)
+
+ virtualenv_opt_args="--system-site-packages"
fi
if ! sudo apt-get install "${host_software_packages[@]}" -y ; then
@@ -114,14 +123,14 @@ print_status_msg "Setting Up Virtual Python Environment"
# delete tbotspython first
sudo rm -rf /opt/tbotspython
-if ! curl -sS https://bootstrap.pypa.io/get-pip.py | sudo /usr/bin/python3.10 ; then
- print_status_msg "Error: Installing pip failed"
+if ! sudo /usr/bin/python3.12 -m venv /opt/tbotspython $virtualenv_opt_args ; then
+ print_status_msg "Error: Setting up virtual environment failed"
exit 1
fi
-if ! sudo /usr/bin/python3.10 -m venv /opt/tbotspython ; then
- print_status_msg "Error: Setting up virtual environment failed"
- exit 1
+if [[ $(lsb_release -rs) == "20.04" ]] || [[ $(lsb_release -rs) == "22.04" ]]; then
+ # Install pip if it is not a system-managed package
+ sudo /usr/bin/python3.12 -m ensurepip
fi
if ! sudo /opt/tbotspython/bin/python3 -m pip install --upgrade pip ; then
@@ -137,32 +146,23 @@ if [[ $(lsb_release -rs) == "22.04" ]]; then
sudo /opt/tbotspython/bin/pip3 install -r ubuntu22_requirements.txt
fi
-print_status_msg "Done Setting Up Virtual Python Environment"
-print_status_msg "Fetching game controller"
+if [[ $(lsb_release -rs) == "24.04" ]]; then
+ sudo /opt/tbotspython/bin/pip3 install -r ubuntu24_requirements.txt
+fi
sudo chown -R $USER:$USER /opt/tbotspython
-sudo wget -N https://github.com/RoboCup-SSL/ssl-game-controller/releases/download/v2.15.2/ssl-game-controller_v2.15.2_linux_amd64 -O /opt/tbotspython/gamecontroller
-sudo chmod +x /opt/tbotspython/gamecontroller
+
+print_status_msg "Done Setting Up Virtual Python Environment"
+print_status_msg "Fetching game controller"
+install_gamecontroller $arch
print_status_msg "Setting up TIGERS AutoRef"
-print_status_msg "Installing TIGERS dependency: Java 17"
-sudo wget -N https://download.oracle.com/java/17/archive/jdk-17.0.5_linux-x64_bin.deb -O /tmp/jdk-17.0.5.deb
-sudo apt install /tmp/./jdk-17.0.5.deb
+print_status_msg "Installing TIGERS dependency: Java 21"
+install_java $arch
print_status_msg "Compiling TIGERS AutoRef"
-sudo wget -N https://github.com/TIGERs-Mannheim/AutoReferee/archive/refs/heads/autoref-ci.zip -O /tmp/autoref-ci.zip
-unzip -q -o -d /tmp/ /tmp/autoref-ci.zip
-touch /tmp/AutoReferee-autoref-ci/.git # a hacky way to make gradle happy when it tries to find a dependency
-
-if ! /tmp/AutoReferee-autoref-ci/./gradlew installDist -p /tmp/AutoReferee-autoref-ci/ -Dorg.gradle.java.home=/usr/lib/jvm/jdk-17/; then
- print_status_msg "Building TIGERS AutoRef failed. Downloading mirror"
-
- wget https://github.com/UBC-Thunderbots/AutoReferee/releases/download/autoref-ci/autoReferee.tar.gz -O /tmp/autoReferee.tar.gz
- tar -xzf /tmp/autoReferee.tar.gz -C /opt/tbotspython/
-else
- cp -r /tmp/AutoReferee-autoref-ci/build/install/autoReferee/ /opt/tbotspython/autoReferee
-fi
+install_autoref $arch
sudo chmod +x "$CURR_DIR/../src/software/autoref/run_autoref.sh"
sudo cp "$CURR_DIR/../src/software/autoref/DIV_B.txt" "/opt/tbotspython/autoReferee/config/geometry/DIV_B.txt"
@@ -172,16 +172,14 @@ print_status_msg "Finished setting up AutoRef"
# Install Bazel
print_status_msg "Installing Bazel"
-# Uninstall Bazel first
-sudo rm -rf $HOME/.bazel
-
-# Adapted from https://docs.bazel.build/versions/main/install-ubuntu.html#install-with-installer-ubuntu
-sudo wget -nc https://github.com/bazelbuild/bazel/releases/download/5.4.0/bazel-5.4.0-installer-linux-x86_64.sh -O /tmp/bazel-installer.sh
-sudo chmod +x /tmp/bazel-installer.sh
-sudo /tmp/bazel-installer.sh --bin=/usr/bin --base=$HOME/.bazel
-echo "source ${HOME}/.bazel/bin/bazel-complete.bash" >> ~/.bashrc
+install_bazel $arch
print_status_msg "Done Installing Bazel"
+
+print_status_msg "Install clang-format"
+install_clang_format $arch
+print_status_msg "Done installing clang-format"
+
print_status_msg "Setting Up PlatformIO"
# setup platformio to compile arduino code
@@ -200,11 +198,16 @@ sudo service udev restart
sudo usermod -a -G dialout $USER
# install PlatformIO to global environment
-if ! sudo /usr/bin/python3.10 -m pip install platformio==6.1.13; then
+wget -O /tmp/tbots_download_cache/get-platformio.py https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py
+if ! /usr/bin/python3.12 /tmp/tbots_download_cache/./get-platformio.py; then
print_status_msg "Error: Installing PlatformIO failed"
exit 1
fi
+# link platformio to /usr/local/bin so that bazel can find it
+sudo rm /usr/local/bin/platformio
+sudo ln -s ~/.platformio/penv/bin/platformio /usr/local/bin/platformio
+
print_status_msg "Done PlatformIO Setup"
print_status_msg "Done Software Setup, please reboot for changes to take place"
diff --git a/environment_setup/ubuntu20_requirements.txt b/environment_setup/ubuntu20_requirements.txt
index 05af883b46..e521b08ed0 100644
--- a/environment_setup/ubuntu20_requirements.txt
+++ b/environment_setup/ubuntu20_requirements.txt
@@ -1,12 +1,10 @@
-protobuf==3.20.2
pyqtgraph==0.13.7
-pyqtdarktheme==2.1.0
-pyqt6==6.5.0
-PyQt6-Qt6==6.5.0
+pyqt6==6.6.1
+PyQt6-Qt6==6.6.1
thefuzz==0.19.0
iterfzf==0.5.0.20.0
-python-Levenshtein==0.12.2
+python-Levenshtein==0.25.1
psutil==5.9.0
PyOpenGL==3.1.6
-numpy==1.24.4
+qt-material==2.12
ruff==0.5.5
diff --git a/environment_setup/ubuntu22_requirements.txt b/environment_setup/ubuntu22_requirements.txt
index 05af883b46..3a9e4d6385 100644
--- a/environment_setup/ubuntu22_requirements.txt
+++ b/environment_setup/ubuntu22_requirements.txt
@@ -1,12 +1,11 @@
-protobuf==3.20.2
pyqtgraph==0.13.7
-pyqtdarktheme==2.1.0
-pyqt6==6.5.0
-PyQt6-Qt6==6.5.0
+pyqt6==6.6.1
+PyQt6-Qt6==6.6.1
thefuzz==0.19.0
iterfzf==0.5.0.20.0
-python-Levenshtein==0.12.2
+python-Levenshtein==0.25.1
psutil==5.9.0
PyOpenGL==3.1.6
-numpy==1.24.4
+numpy==1.26.4
+qt-material==2.12
ruff==0.5.5
diff --git a/environment_setup/ubuntu24_requirements.txt b/environment_setup/ubuntu24_requirements.txt
new file mode 100644
index 0000000000..983fcdda89
--- /dev/null
+++ b/environment_setup/ubuntu24_requirements.txt
@@ -0,0 +1,8 @@
+pyqtgraph==0.13.7
+thefuzz==0.19.0
+iterfzf==0.5.0.20.0
+python-Levenshtein==0.25.1
+psutil==5.9.0
+PyOpenGL==3.1.6
+qt-material==2.12
+ruff==0.5.5
diff --git a/environment_setup/util.sh b/environment_setup/util.sh
new file mode 100755
index 0000000000..e72046ad56
--- /dev/null
+++ b/environment_setup/util.sh
@@ -0,0 +1,91 @@
+install_autoref() {
+ autoref_commit=b30660b78728c3ce159de8ae096181a1ec52e9ba
+ sudo wget -N https://github.com/TIGERs-Mannheim/AutoReferee/archive/${autoref_commit}.zip -O /tmp/tbots_download_cache/autoReferee.zip
+ unzip -q -o -d /tmp/tbots_download_cache/ /tmp/tbots_download_cache/autoReferee.zip
+
+ /tmp/tbots_download_cache/AutoReferee-${autoref_commit}/./gradlew installDist -p /tmp/tbots_download_cache/AutoReferee-${autoref_commit} -Dorg.gradle.java.home=/opt/tbotspython/bin/jdk
+ mv /tmp/tbots_download_cache/AutoReferee-${autoref_commit}/build/install/autoReferee /opt/tbotspython/
+}
+
+install_bazel() {
+ download=https://github.com/bazelbuild/bazel/releases/download/5.4.0/bazel-5.4.0-linux-arm64
+
+ if is_x86 $1; then
+ download=https://github.com/bazelbuild/bazel/releases/download/5.4.0/bazel-5.4.0-linux-x86_64
+ fi
+
+ wget -nc $download -O /tmp/tbots_download_cache/bazel
+ sudo mv /tmp/tbots_download_cache/bazel /usr/bin/bazel
+ sudo chmod +x /usr/bin/bazel
+}
+
+install_clang_format() {
+ download=https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-aarch64-linux-gnu.tar.xz
+ clang_format_path=/tmp/tbots_download_cache/clang+llvm-10.0.0-aarch64-linux-gnu/bin/clang-format
+
+ if is_x86 $1; then
+ download=https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz
+ clang_format_path=/tmp/tbots_download_cache/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04/bin/clang-format
+ fi
+
+ wget $download -O /tmp/tbots_download_cache/clang.tar.xz
+ tar -xf /tmp/tbots_download_cache/clang.tar.xz -C /tmp/tbots_download_cache/
+ sudo cp $clang_format_path /opt/tbotspython/bin/clang-format
+}
+
+install_gamecontroller () {
+ # TODO(#3335): Whenever we deprecate Ubuntu 20.04, we can just grab the latest version of the SSL game controller
+ # binary from the releases page. This is a workaround since the latest version of the game controller is compiled
+ # with a newer GLIBC version than what is available on Ubuntu 20.04.
+ go_arch=arm64
+ if is_x86 $1; then
+ go_arch=amd64
+ fi
+ sudo wget -N https://go.dev/dl/go1.23.0.linux-${go_arch}.tar.gz -O /tmp/tbots_download_cache/go.tar.gz
+ tar -C /tmp/tbots_download_cache -xf /tmp/tbots_download_cache/go.tar.gz
+ export PATH=$PATH:/tmp/tbots_download_cache/go/bin
+ sudo wget -N https://github.com/RoboCup-SSL/ssl-game-controller/archive/refs/tags/v3.12.3.zip -O /tmp/tbots_download_cache/ssl-game-controller.zip
+ unzip -q -o -d /tmp/tbots_download_cache/ /tmp/tbots_download_cache/ssl-game-controller.zip
+ cd /tmp/tbots_download_cache/ssl-game-controller-3.12.3
+
+ # Installing nvm
+ wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
+ export NVM_DIR="$HOME/.nvm"
+ [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
+ [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
+ nvm install 20
+
+ make install
+ go build cmd/ssl-game-controller/main.go
+ sudo mv main /opt/tbotspython/gamecontroller
+ sudo chmod +x /opt/tbotspython/gamecontroller
+
+ cd -
+ sudo rm -rf /tmp/tbots_download_cache/ssl-game-controller-3.12.3
+ sudo rm -rf /tmp/tbots_download_cache/go
+}
+
+install_java () {
+ java_home=""
+ java_download=https://download.oracle.com/java/21/latest/jdk-21_linux-aarch64_bin.tar.gz
+ if is_x86 $1; then
+ java_download=https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.tar.gz
+ fi
+ sudo wget -N $java_download -O /tmp/tbots_download_cache/jdk-21.tar.gz
+ tar -xzf /tmp/tbots_download_cache/jdk-21.tar.gz -C /opt/tbotspython/
+ mv /opt/tbotspython/jdk-21* /opt/tbotspython/bin/jdk
+}
+
+is_x86() {
+ if [[ $1 == "x86_64" ]]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+print_status_msg () {
+ echo "================================================================"
+ echo $1
+ echo "================================================================"
+}
diff --git a/scripts/clang-format-10.0 b/scripts/clang-format-10.0
deleted file mode 100755
index c3b9422c90..0000000000
Binary files a/scripts/clang-format-10.0 and /dev/null differ
diff --git a/scripts/compile_pip_requirements.sh b/scripts/compile_pip_requirements.sh
index dd2bce5e88..becf00a925 100755
--- a/scripts/compile_pip_requirements.sh
+++ b/scripts/compile_pip_requirements.sh
@@ -17,5 +17,5 @@ BAZEL_ROOT_DIR="$CURR_DIR/../src"
cd $BAZEL_ROOT_DIR
bazel run //extlibs:nanopb_requirements.update
bazel run //software/thunderscope:requirements.update
-bazel run //software/jetson_nano/ansible:requirements.update
+bazel run //software/embedded/ansible:requirements.update
bazel run //software/simulated_tests:requirements.update
diff --git a/scripts/lint_and_format.sh b/scripts/lint_and_format.sh
index 8982f4ff5a..0f6fc83187 100755
--- a/scripts/lint_and_format.sh
+++ b/scripts/lint_and_format.sh
@@ -10,6 +10,9 @@ export CLANG_VERSION=10.0
# The directory this script is in
CURR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+# The path to clang-format
+export CLANG_BIN=/opt/tbotspython/bin/clang-format
+
# The root bazel directory
BAZEL_ROOT_DIR="$CURR_DIR/../src"
@@ -33,7 +36,7 @@ function run_clang_format () {
# clang-format as arguments
# We remove the last -o flag from the extension string
find $CURR_DIR/../src/ ${EXTENSION_STRING::-2} \
- | xargs -I{} -n1000 $CURR_DIR/clang-format-$CLANG_VERSION -i -style=file
+ | xargs -I{} -n1000 $CLANG_BIN -i -style=file
if [[ "$?" != 0 ]]; then
printf "\n***Failed to run clang-format over all files!***\n\n"
diff --git a/src/.bazelrc b/src/.bazelrc
index 1df5a1234b..8f694e5535 100644
--- a/src/.bazelrc
+++ b/src/.bazelrc
@@ -10,7 +10,7 @@ test --test_output=all
build --crosstool_top=//cc_toolchain:toolchain
# Add warnings to Thunderbots code only
-build --per_file_copt=//proto/message_translation/.*,//proto/primitive/.*,//software/.*,//shared/.*@-Wall,-Wextra,-Wconversion,-Wno-unused-parameter,-Wno-deprecated,-Werror
+build --per_file_copt=//proto/.*,//proto/message_translation/.*,//proto/primitive/.*,//software/.*,//shared/.*@-Wall,-Wextra,-Wconversion,-Wno-unused-parameter,-Wno-deprecated,-Werror,-Wno-deprecated-declarations
# Warn variable length arrays only when compiling cpp
build --per_file_copt=.*\.cpp@-Wvla
@@ -31,5 +31,9 @@ build --test_env=XDG_RUNTIME_DIR
build --test_env=DISPLAY
# Setup python bin/lib to point to our venv
-build --action_env=PYTHON_BIN_PATH=/opt/tbotspython/bin/python3.10
-build --action_env=PYTHON_LIB_PATH=/opt/tbotspython/lib/python3.10
+build --action_env=PYTHON_BIN_PATH=/opt/tbotspython/bin/python3.12
+build --action_env=PYTHON_LIB_PATH=/opt/tbotspython/lib/python3.12
+
+# Enable the new cc_toolchain resolution strategy
+# #TODO(#3382): Delete when we upgrade to Bazel 7.0
+build --incompatible_enable_cc_toolchain_resolution
diff --git a/src/MODULE.bazel b/src/MODULE.bazel
new file mode 100644
index 0000000000..bfd76eecbf
--- /dev/null
+++ b/src/MODULE.bazel
@@ -0,0 +1 @@
+bazel_dep(name = "bazel_skylib", version = "1.5.0")
diff --git a/src/WORKSPACE b/src/WORKSPACE
index 790a388d2c..1814824150 100644
--- a/src/WORKSPACE
+++ b/src/WORKSPACE
@@ -46,7 +46,7 @@ pip_parse(
pip_parse(
name = "ansible_deps",
python_interpreter = "/opt/tbotspython/bin/python",
- requirements_lock = "//software/jetson_nano/ansible:requirements_lock.txt",
+ requirements_lock = "//software/embedded/ansible:requirements_lock.txt",
)
pip_parse(
@@ -104,9 +104,9 @@ http_archive(
http_archive(
name = "g3log",
build_file = "@//extlibs:g3log.BUILD",
- sha256 = "176fcf4e1634aba425549c32f76426d7976ab6973370785fd6b76986e9f7b20e",
- strip_prefix = "g3log-1.3.3",
- url = "https://github.com/KjellKod/g3log/archive/1.3.3.zip",
+ sha256 = "2177e6dfd86fa7465c44c8ef5c3b6ab98ffc94e1130355d6982f7d886cb7bec9",
+ strip_prefix = "g3log-2.4",
+ url = "https://github.com/KjellKod/g3log/archive/refs/tags/2.4.zip",
)
http_archive(
@@ -142,9 +142,9 @@ protobuf_deps()
git_repository(
name = "com_github_nelhage_rules_boost",
- commit = "7332c6cf2afb2642f53bc23f9b4d9c1817318685",
+ commit = "58be4e7e851d19e9ba14ced7bdba6fc8895af1d3",
remote = "https://github.com/nelhage/rules_boost",
- shallow_since = "1606097530 -0500",
+ shallow_since = "1724946929 +0200",
)
git_repository(
@@ -214,25 +214,15 @@ git_repository(
shallow_since = "1571237073 -0500",
)
-# Qt bazel rules from https://github.com/justbuchanan/bazel_rules_qt
-git_repository(
- name = "bazel_rules_qt",
- commit = "7665177f47bf514176d5f8575a7334f030203e3d",
- remote = "https://github.com/justbuchanan/bazel_rules_qt.git",
- shallow_since = "1614109311 -0800",
-)
-
-# Right now qt5 is installed on the system using the setup_software.sh script
-# We assume we can find the headers in the "standard" path used in this rule
new_local_repository(
- name = "qt",
- build_file = "@bazel_rules_qt//:qt.BUILD",
- path = "/usr/include/x86_64-linux-gnu/qt5/",
+ name = "linux_k8_gcc",
+ build_file = "@//extlibs:linux_k8_gcc.BUILD",
+ path = "/",
)
new_local_repository(
- name = "linux_gcc",
- build_file = "@//extlibs:linux_gcc.BUILD",
+ name = "linux_aarch64_gcc",
+ build_file = "@//extlibs:linux_aarch64_gcc.BUILD",
path = "/",
)
@@ -244,8 +234,8 @@ new_local_repository(
)
http_archive(
- name = "jetson_nano_gcc",
- build_file = "@//extlibs:jetson_nano_gcc.BUILD",
+ name = "k8_jetson_nano_cross_compile_gcc",
+ build_file = "@//extlibs:k8_jetson_nano_cross_compile_gcc.BUILD",
sha256 = "73eed74e593e2267504efbcf3678918bb22409ab7afa3dc7c135d2c6790c2345",
strip_prefix = "gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu",
urls = [
@@ -348,9 +338,9 @@ http_archive(
http_archive(
name = "pybind11",
build_file = "@pybind11_bazel//:pybind11.BUILD",
- sha256 = "1c6e0141f7092867c5bf388bc3acdb2689ed49f59c3977651394c6c87ae88232",
- strip_prefix = "pybind11-2.9.0",
- urls = ["https://github.com/pybind/pybind11/archive/refs/tags/v2.9.0.zip"],
+ sha256 = "411f77380c43798506b39ec594fc7f2b532a13c4db674fcf2b1ca344efaefb68",
+ strip_prefix = "pybind11-2.12.0",
+ urls = ["https://github.com/pybind/pybind11/archive/refs/tags/v2.12.0.zip"],
)
load("@pybind11_bazel//:python_configure.bzl", "python_configure")
@@ -402,3 +392,9 @@ new_git_repository(
remote = "https://github.com/wolfpld/tracy.git",
shallow_since = "1697482622 +0200",
)
+
+register_toolchains(
+ "//cc_toolchain:cc_toolchain_for_k8_jetson_nano_cross_compile",
+ "//cc_toolchain:cc_toolchain_for_k8",
+ "//cc_toolchain:cc_toolchain_for_aarch64",
+)
diff --git a/src/cc_toolchain/BUILD b/src/cc_toolchain/BUILD
index 60c869dfed..d5396df343 100644
--- a/src/cc_toolchain/BUILD
+++ b/src/cc_toolchain/BUILD
@@ -1,46 +1,69 @@
package(default_visibility = ["//visibility:public"])
-load(":cc_toolchain_config.bzl", "cc_toolchain_config_jetson_nano", "cc_toolchain_config_k8")
+load(
+ ":cc_toolchain_config.bzl",
+ "cc_toolchain_config_fullsystem",
+ "cc_toolchain_config_k8_jetson_nano_cross_compile",
+ "make_builtin_include_directories",
+)
# Create environments for each CPU this toolchain supports
environment(name = "k8")
-environment(name = "jetson_nano")
+environment(name = "k8_jetson_nano_cross_compile")
+
+environment(name = "aarch64")
environment_group(
name = "cpus",
defaults = [
+ ":aarch64",
":k8",
- ":jetson_nano",
+ ":k8_jetson_nano_cross_compile",
],
environments = [
+ ":aarch64",
":k8",
- ":jetson_nano",
+ ":k8_jetson_nano_cross_compile",
],
)
+config_setting(
+ name = "cpu_aarch64",
+ values = {"cpu": "aarch64"},
+)
+
config_setting(
name = "cpu_k8",
values = {"cpu": "k8"},
)
config_setting(
- name = "cpu_jetson_nano",
- values = {"cpu": "jetson_nano"},
+ name = "cpu_k8_jetson_nano_cross_compile",
+ values = {"cpu": "k8_jetson_nano_cross_compile"},
+)
+
+platform(
+ name = "robot",
+ constraint_values = [
+ "@platforms//cpu:aarch64",
+ "@platforms//os:linux",
+ ],
)
# This represents a mapping of CPU -> Compiler To Use
-# The CPU can be chosen by using `--cpu` as a bazel flag (ex. `--cpu=jetson_nano`)
-# otherwise it will default to using whatever CPU is in the system doing the compiling
cc_toolchain_suite(
name = "toolchain",
toolchains = {
# k8 is any x86 system
- "k8": "cc_toolchain_linux_gcc",
- "k8|compiler": "cc_toolchain_linux_gcc",
+ "k8": "cc_toolchain_linux_k8_gcc",
+ "k8|compiler": "cc_toolchain_linux_k8_gcc",
+ # aarch64 is for ARM64 systems and the robot
+ "aarch64": "cc_toolchain_linux_aarch64_gcc",
+ "aarch64|compiler": "cc_toolchain_linux_aarch64_gcc",
# jetson nano 4GB system
- "jetson_nano": "cc_toolchain_jetson_nano",
- "jetson_nano|compiler": "cc_toolchain_jetson_nano",
+ "k8_jetson_nano_cross_compile": "cc_toolchain_k8_jetson_nano_cross_compile",
+ "k8_jetson_nano_cross_compile|compiler": "cc_toolchain_k8_jetson_nano_cross_compile",
},
)
@@ -50,10 +73,10 @@ filegroup(
)
filegroup(
- name = "jetson_nano_everything",
+ name = "k8_jetson_nano_cross_compile_everything",
srcs = [
- "@jetson_nano_gcc//:everything",
- ] + glob(["wrapper/jetson_nano_*"]),
+ "@k8_jetson_nano_cross_compile_gcc//:everything",
+ ] + glob(["wrapper/k8_jetson_nano_cross_compile_*"]),
)
filegroup(
@@ -62,71 +85,95 @@ filegroup(
)
filegroup(
- name = "linux_gcc_all",
+ name = "linux_k8_gcc_all",
+ srcs = [
+ ":linux_gcc_wrapper",
+ "@linux_k8_gcc//:includes",
+ "@linux_k8_gcc//:libs",
+ "@linux_k8_gcc//:runtime_libs",
+ "@linux_k8_gcc//:static_libs",
+ ],
+)
+
+filegroup(
+ name = "linux_aarch64_gcc_all",
srcs = [
":linux_gcc_wrapper",
- "@linux_gcc//:includes",
- "@linux_gcc//:libs",
- "@linux_gcc//:runtime_libs",
- "@linux_gcc//:static_libs",
+ "@linux_aarch64_gcc//:includes",
+ "@linux_aarch64_gcc//:libs",
+ "@linux_aarch64_gcc//:runtime_libs",
+ "@linux_aarch64_gcc//:static_libs",
],
)
-cc_toolchain_config_k8(
- name = "linux_gcc",
+cc_toolchain_config_fullsystem(
+ name = "linux_k8_gcc",
builtin_include_directories = [
"/usr/lib/gcc/x86_64-linux-gnu/",
- "/usr/include/",
- "/usr/local/include/",
- "/usr/lib/gcc/c++/*/include/",
- ],
- cpu = "k8",
+ ] + make_builtin_include_directories(),
+ host_system_name = "k8",
target_cpu = "k8",
target_system_name = "k8",
- tool_paths = {
- "ar": "/usr/bin/ar",
- "cpp": "/usr/bin/cpp",
- "dwp": "/usr/bin/dwp",
- "gcc": "wrapper/linux_gcc",
- "gcov": "/usr/bin/gcov",
- "ld": "/usr/bin/ld",
- "nm": "/usr/bin/nm",
- "objcopy": "/usr/bin/objcopy",
- "objdump": "/usr/bin/objdump",
- "strip": "/usr/bin/strip",
- },
- toolchain_identifier = "linux_gcc-k8",
+ toolchain_identifier = "linux_k8_gcc",
+)
+
+cc_toolchain_config_fullsystem(
+ name = "linux_aarch64_gcc",
+ builtin_include_directories = [
+ "/usr/lib/gcc/aarch64-linux-gnu/",
+ ] + make_builtin_include_directories(),
+ host_system_name = "aarch64",
+ target_cpu = "aarch64",
+ target_system_name = "aarch64",
+ toolchain_identifier = "linux_aarch64_gcc",
)
cc_toolchain(
- name = "cc_toolchain_linux_gcc",
- all_files = ":linux_gcc_all",
- ar_files = ":linux_gcc_all",
- as_files = ":linux_gcc_all",
- compiler_files = ":linux_gcc_all",
- dwp_files = ":linux_gcc_all",
- dynamic_runtime_lib = "@linux_gcc//:runtime_libs",
- linker_files = ":linux_gcc_all",
- objcopy_files = ":linux_gcc_all",
- static_runtime_lib = "@linux_gcc//:static_libs",
- strip_files = ":linux_gcc_all",
+ name = "cc_toolchain_linux_k8_gcc",
+ all_files = ":linux_k8_gcc_all",
+ ar_files = ":linux_k8_gcc_all",
+ as_files = ":linux_k8_gcc_all",
+ compiler_files = ":linux_k8_gcc_all",
+ dwp_files = ":linux_k8_gcc_all",
+ dynamic_runtime_lib = "@linux_k8_gcc//:runtime_libs",
+ linker_files = ":linux_k8_gcc_all",
+ objcopy_files = ":linux_k8_gcc_all",
+ static_runtime_lib = "@linux_k8_gcc//:static_libs",
+ strip_files = ":linux_k8_gcc_all",
supports_param_files = True,
# We add this tag to circumvent a bug in the CLion bazel plugin. It should be removed
# when possible
# https://github.com/bazelbuild/intellij/issues/486
tags = ["no-ide"],
- toolchain_config = ":linux_gcc",
- toolchain_identifier = "k8_gcc-x86_64",
+ toolchain_config = ":linux_k8_gcc",
+ toolchain_identifier = "k8_gcc",
)
cc_toolchain(
- name = "cc_toolchain_jetson_nano",
- all_files = ":jetson_nano_everything",
- ar_files = ":jetson_nano_everything",
- as_files = ":jetson_nano_everything",
- compiler_files = ":jetson_nano_everything",
+ name = "cc_toolchain_linux_aarch64_gcc",
+ all_files = ":linux_aarch64_gcc_all",
+ ar_files = ":linux_aarch64_gcc_all",
+ as_files = ":linux_aarch64_gcc_all",
+ compiler_files = ":linux_aarch64_gcc_all",
+ dwp_files = ":linux_aarch64_gcc_all",
+ dynamic_runtime_lib = "@linux_aarch64_gcc//:runtime_libs",
+ linker_files = ":linux_aarch64_gcc_all",
+ objcopy_files = ":linux_aarch64_gcc_all",
+ static_runtime_lib = "@linux_aarch64_gcc//:static_libs",
+ strip_files = ":linux_aarch64_gcc_all",
+ supports_param_files = True,
+ toolchain_config = ":linux_aarch64_gcc",
+ toolchain_identifier = "aarch64_gcc",
+)
+
+cc_toolchain(
+ name = "cc_toolchain_k8_jetson_nano_cross_compile",
+ all_files = ":k8_jetson_nano_cross_compile_everything",
+ ar_files = ":k8_jetson_nano_cross_compile_everything",
+ as_files = ":k8_jetson_nano_cross_compile_everything",
+ compiler_files = ":k8_jetson_nano_cross_compile_everything",
dwp_files = ":empty",
- linker_files = ":jetson_nano_everything",
+ linker_files = ":k8_jetson_nano_cross_compile_everything",
objcopy_files = ":empty",
strip_files = ":empty",
supports_param_files = 0,
@@ -134,30 +181,71 @@ cc_toolchain(
# when possible
# https://github.com/bazelbuild/intellij/issues/486
tags = ["no-ide"],
- toolchain_config = ":gcc-jetson_nano",
- toolchain_identifier = "gcc-jetson_nano",
+ toolchain_config = ":gcc_k8_jetson_nano_cross_compile",
+ toolchain_identifier = "gcc-k8-jetson-nano-cross-compile",
)
-cc_toolchain_config_jetson_nano(
- name = "gcc-jetson_nano",
+cc_toolchain_config_k8_jetson_nano_cross_compile(
+ name = "gcc_k8_jetson_nano_cross_compile",
builtin_include_directories = [
- "external/jetson_nano_gcc/include/",
- "external/jetson_nano_gcc/aarch64-linux-gnu/include/",
- "external/jetson_nano_gcc/aarch64-linux-gnu/libc/lib/",
- "external/jetson_nano_gcc/aarch64-linux-gnu/libc/usr/include/",
+ "external/k8_jetson_nano_cross_compile_gcc/include/",
+ "external/k8_jetson_nano_cross_compile_gcc/aarch64-linux-gnu/include/",
+ "external/k8_jetson_nano_cross_compile_gcc/aarch64-linux-gnu/libc/lib/",
+ "external/k8_jetson_nano_cross_compile_gcc/aarch64-linux-gnu/libc/usr/include/",
],
- cpu = "jetson_nano",
tool_paths = {
- "ar": "wrapper/jetson_nano_ar",
- "cpp": "wrapper/jetson_nano_cpp",
- "dwp": "wrapper/jetson_nano_dwp",
- "gcc": "wrapper/jetson_nano_gcc",
- "gcov": "wrapper/jetson_nano_gcov",
- "ld": "wrapper/jetson_nano_ld",
- "nm": "wrapper/jetson_nano_nm",
- "objcopy": "wrapper/jetson_nano_objcopy",
- "objdump": "wrapper/jetson_nano_objdump",
- "strip": "wrapper/jetson_nano_strip",
+ "ar": "wrapper/k8_jetson_nano_cross_compile_ar",
+ "cpp": "wrapper/k8_jetson_nano_cross_compile_cpp",
+ "dwp": "wrapper/k8_jetson_nano_cross_compile_dwp",
+ "gcc": "wrapper/k8_jetson_nano_cross_compile_gcc",
+ "gcov": "wrapper/k8_jetson_nano_cross_compile_gcov",
+ "ld": "wrapper/k8_jetson_nano_cross_compile_ld",
+ "nm": "wrapper/k8_jetson_nano_cross_compile_nm",
+ "objcopy": "wrapper/k8_jetson_nano_cross_compile_objcopy",
+ "objdump": "wrapper/k8_jetson_nano_cross_compile_objdump",
+ "strip": "wrapper/k8_jetson_nano_cross_compile_strip",
},
- toolchain_identifier = "gcc-jetson_nano",
+ toolchain_identifier = "gcc-k8-jetson_nano-cross-compile",
+)
+
+toolchain(
+ name = "cc_toolchain_for_k8_jetson_nano_cross_compile",
+ exec_compatible_with = [
+ "@platforms//cpu:x86_64",
+ "@platforms//os:linux",
+ ],
+ target_compatible_with = [
+ "@platforms//cpu:aarch64",
+ "@platforms//os:linux",
+ ],
+ toolchain = ":cc_toolchain_k8_jetson_nano_cross_compile",
+ toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
+)
+
+toolchain(
+ name = "cc_toolchain_for_k8",
+ exec_compatible_with = [
+ "@platforms//os:linux",
+ "@platforms//cpu:x86_64",
+ ],
+ target_compatible_with = [
+ "@platforms//os:linux",
+ "@platforms//cpu:x86_64",
+ ],
+ toolchain = ":cc_toolchain_linux_k8_gcc",
+ toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
+)
+
+toolchain(
+ name = "cc_toolchain_for_aarch64",
+ exec_compatible_with = [
+ "@platforms//cpu:aarch64",
+ "@platforms//os:linux",
+ ],
+ target_compatible_with = [
+ "@platforms//cpu:aarch64",
+ "@platforms//os:linux",
+ ],
+ toolchain = ":cc_toolchain_linux_aarch64_gcc",
+ toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)
diff --git a/src/cc_toolchain/cc_toolchain_config.bzl b/src/cc_toolchain/cc_toolchain_config.bzl
index 00f9e08373..1544046401 100644
--- a/src/cc_toolchain/cc_toolchain_config.bzl
+++ b/src/cc_toolchain/cc_toolchain_config.bzl
@@ -104,6 +104,27 @@ ALL_CPP_ACTIONS = [
ACTION_NAMES.cpp_link_nodeps_dynamic_library,
]
+def make_builtin_include_directories():
+ return [
+ "/usr/include/",
+ "/usr/local/include/",
+ "/usr/lib/gcc/c++/*/include/",
+ ]
+
+def _make_common_toolpaths():
+ return {
+ "ar": "/usr/bin/ar",
+ "cpp": "/usr/bin/cpp",
+ "dwp": "/usr/bin/dwp",
+ "gcc": "wrapper/linux_gcc",
+ "gcov": "/usr/bin/gcov",
+ "ld": "/usr/bin/ld",
+ "nm": "/usr/bin/nm",
+ "objcopy": "/usr/bin/objcopy",
+ "objdump": "/usr/bin/objdump",
+ "strip": "/usr/bin/strip",
+ }
+
def _make_common_features(ctx):
result = {}
@@ -401,13 +422,11 @@ def _make_common_features(ctx):
return result
def _linux_gcc_impl(ctx):
- host_system_name = "k8"
-
action_configs = []
tool_paths = [
tool_path(name = name, path = path)
- for name, path in ctx.attr.tool_paths.items()
+ for name, path in _make_common_toolpaths().items()
]
common = _make_common_features(ctx)
@@ -560,7 +579,7 @@ def _linux_gcc_impl(ctx):
artifact_name_patterns = [],
cxx_builtin_include_directories = ctx.attr.builtin_include_directories,
toolchain_identifier = ctx.attr.toolchain_identifier,
- host_system_name = host_system_name,
+ host_system_name = ctx.attr.host_system_name,
target_system_name = ctx.attr.target_system_name,
target_cpu = ctx.attr.target_cpu,
target_libc = "libc",
@@ -577,14 +596,14 @@ def _linux_gcc_impl(ctx):
),
]
-cc_toolchain_config_k8 = rule(
+cc_toolchain_config_fullsystem = rule(
implementation = _linux_gcc_impl,
attrs = {
"builtin_include_directories": attr.string_list(),
- "cpu": attr.string(mandatory = True, values = ["k8"]),
"extra_features": attr.string_list(),
"extra_no_canonical_prefixes_flags": attr.string_list(),
"host_compiler_warnings": attr.string_list(),
+ "host_system_name": attr.string(),
"host_unfiltered_compile_flags": attr.string_list(),
"target_cpu": attr.string(),
"target_system_name": attr.string(),
@@ -595,7 +614,7 @@ cc_toolchain_config_k8 = rule(
executable = True,
)
-def _jetson_nano_impl(ctx):
+def _k8_jetson_nano_cross_compile_impl(ctx):
host_system_name = "k8"
action_configs = []
@@ -708,12 +727,9 @@ def _jetson_nano_impl(ctx):
),
]
-cc_toolchain_config_jetson_nano = rule(
- implementation = _jetson_nano_impl,
+cc_toolchain_config_k8_jetson_nano_cross_compile = rule(
+ implementation = _k8_jetson_nano_cross_compile_impl,
attrs = {
- "cpu": attr.string(mandatory = True, values = [
- "jetson_nano",
- ]),
"builtin_include_directories": attr.string_list(),
"extra_no_canonical_prefixes_flags": attr.string_list(),
"host_compiler_warnings": attr.string_list(),
diff --git a/src/cc_toolchain/wrapper/jetson_nano_ar b/src/cc_toolchain/wrapper/jetson_nano_ar
deleted file mode 100755
index d40a860b6e..0000000000
--- a/src/cc_toolchain/wrapper/jetson_nano_ar
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash --norc
-
-exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-ar "$@"
diff --git a/src/cc_toolchain/wrapper/jetson_nano_cpp b/src/cc_toolchain/wrapper/jetson_nano_cpp
deleted file mode 100755
index aff3764d78..0000000000
--- a/src/cc_toolchain/wrapper/jetson_nano_cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash --norc
-
-exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-cpp "$@"
diff --git a/src/cc_toolchain/wrapper/jetson_nano_g++ b/src/cc_toolchain/wrapper/jetson_nano_g++
deleted file mode 100755
index b8f943f7e3..0000000000
--- a/src/cc_toolchain/wrapper/jetson_nano_g++
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash --norc
-
-exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-g++ -Wl,--no-as-needed "$@"
diff --git a/src/cc_toolchain/wrapper/jetson_nano_gcc b/src/cc_toolchain/wrapper/jetson_nano_gcc
deleted file mode 100755
index 64774504ab..0000000000
--- a/src/cc_toolchain/wrapper/jetson_nano_gcc
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash --norc
-
-exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-gcc -Wl,--no-as-needed "$@"
diff --git a/src/cc_toolchain/wrapper/jetson_nano_gcov b/src/cc_toolchain/wrapper/jetson_nano_gcov
deleted file mode 100755
index 7922e92416..0000000000
--- a/src/cc_toolchain/wrapper/jetson_nano_gcov
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash --norc
-
-exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-gcov "$@"
diff --git a/src/cc_toolchain/wrapper/jetson_nano_ld b/src/cc_toolchain/wrapper/jetson_nano_ld
deleted file mode 100755
index 51728eeb07..0000000000
--- a/src/cc_toolchain/wrapper/jetson_nano_ld
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash --norc
-
-exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-ld "$@"
diff --git a/src/cc_toolchain/wrapper/jetson_nano_nm b/src/cc_toolchain/wrapper/jetson_nano_nm
deleted file mode 100755
index 98c9a6ba28..0000000000
--- a/src/cc_toolchain/wrapper/jetson_nano_nm
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash --norc
-
-exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-nm "$@"
diff --git a/src/cc_toolchain/wrapper/jetson_nano_objcopy b/src/cc_toolchain/wrapper/jetson_nano_objcopy
deleted file mode 100755
index 70ff1f0e61..0000000000
--- a/src/cc_toolchain/wrapper/jetson_nano_objcopy
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash --norc
-
-exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-objcopy "$@"
diff --git a/src/cc_toolchain/wrapper/jetson_nano_objdump b/src/cc_toolchain/wrapper/jetson_nano_objdump
deleted file mode 100755
index b17ce50c8c..0000000000
--- a/src/cc_toolchain/wrapper/jetson_nano_objdump
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash --norc
-
-exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-objdump "$@"
diff --git a/src/cc_toolchain/wrapper/jetson_nano_strip b/src/cc_toolchain/wrapper/jetson_nano_strip
deleted file mode 100755
index 1d67bf46c0..0000000000
--- a/src/cc_toolchain/wrapper/jetson_nano_strip
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash --norc
-
-exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-strip "$@"
diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_ar b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_ar
new file mode 100755
index 0000000000..233d5e3c4c
--- /dev/null
+++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_ar
@@ -0,0 +1,3 @@
+#!/bin/bash --norc
+
+exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-ar "$@"
diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_cpp b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_cpp
new file mode 100755
index 0000000000..8977e9e4fd
--- /dev/null
+++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_cpp
@@ -0,0 +1,3 @@
+#!/bin/bash --norc
+
+exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-cpp "$@"
diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_g++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_g++
new file mode 100755
index 0000000000..a3f3025445
--- /dev/null
+++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_g++
@@ -0,0 +1,3 @@
+#!/bin/bash --norc
+
+exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-g++ -Wl,--no-as-needed "$@"
diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_gcc b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_gcc
new file mode 100755
index 0000000000..cad72ed459
--- /dev/null
+++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_gcc
@@ -0,0 +1,3 @@
+#!/bin/bash --norc
+
+exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-gcc -Wl,--no-as-needed "$@"
diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_gcov b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_gcov
new file mode 100755
index 0000000000..7c3616749d
--- /dev/null
+++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_gcov
@@ -0,0 +1,3 @@
+#!/bin/bash --norc
+
+exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-gcov "$@"
diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_ld b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_ld
new file mode 100755
index 0000000000..7ed51ae2b3
--- /dev/null
+++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_ld
@@ -0,0 +1,3 @@
+#!/bin/bash --norc
+
+exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-ld "$@"
diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_nm b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_nm
new file mode 100755
index 0000000000..2eb52826c7
--- /dev/null
+++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_nm
@@ -0,0 +1,3 @@
+#!/bin/bash --norc
+
+exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-nm "$@"
diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_objcopy b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_objcopy
new file mode 100755
index 0000000000..2b324ad0cc
--- /dev/null
+++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_objcopy
@@ -0,0 +1,3 @@
+#!/bin/bash --norc
+
+exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-objcopy "$@"
diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_objdump b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_objdump
new file mode 100755
index 0000000000..1b69911e81
--- /dev/null
+++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_objdump
@@ -0,0 +1,3 @@
+#!/bin/bash --norc
+
+exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-objdump "$@"
diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_strip b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_strip
new file mode 100755
index 0000000000..67a975cc89
--- /dev/null
+++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_strip
@@ -0,0 +1,3 @@
+#!/bin/bash --norc
+
+exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-strip "$@"
diff --git a/src/cc_toolchain/wrapper/linux_gcc b/src/cc_toolchain/wrapper/linux_gcc
index 9c27b70983..e0800abb9c 100755
--- a/src/cc_toolchain/wrapper/linux_gcc
+++ b/src/cc_toolchain/wrapper/linux_gcc
@@ -6,4 +6,4 @@
# only link in the direct dependencies for each shared lib, but because
# bazel delays linking to the end of the build, this means some (non-direct)
# dependencies of the final target will not be linked in
-exec /usr/bin/gcc-9 -Wl,--no-as-needed "$@"
+exec /usr/bin/gcc-10 -Wl,--no-as-needed "$@"
diff --git a/src/extlibs/er_force_sim/README.md b/src/extlibs/er_force_sim/README.md
index c6a65ed338..257a2e5dbe 100644
--- a/src/extlibs/er_force_sim/README.md
+++ b/src/extlibs/er_force_sim/README.md
@@ -1,7 +1,11 @@
# The Simulator from Roboterfußballmannschaft der Friedrich-Alexander-Universität Erlangen-Nürnberg Robotics Erlangen's SSL-Team ER-Force's Framework
-The simulator was adapted from [robotics-erlangen/framework](https://github.com/robotics-erlangen/framework). It was modified so that time steps could be controlled by a stepSimulation function.
+
+The simulator is adapted from [robotics-erlangen/framework](https://github.com/robotics-erlangen/framework). It contains several bug fixes and general code quality improvements, and it is modified so that time steps can be controlled by a `stepSimulation` function.
+
## Copyright
+
+```
/***************************************************************************
* Copyright 2020 Michael Eischer, Philipp Nordhus, Andreas Wendler *
* Robotics Erlangen e.V. *
@@ -21,3 +25,4 @@ The simulator was adapted from [robotics-erlangen/framework](https://github.com/
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see . *
***************************************************************************/
+```
diff --git a/src/extlibs/er_force_sim/src/amun/simulator/BUILD b/src/extlibs/er_force_sim/src/amun/simulator/BUILD
index 76473358a4..69a9a7b732 100644
--- a/src/extlibs/er_force_sim/src/amun/simulator/BUILD
+++ b/src/extlibs/er_force_sim/src/amun/simulator/BUILD
@@ -1,21 +1,15 @@
-load("@bazel_rules_qt//:qt.bzl", "qt_cc_library")
-
package(default_visibility = ["//visibility:public"])
-qt_cc_library(
- name = "simulator_qt",
+cc_library(
+ name = "simulator",
srcs = glob(["*.cpp"]),
hdrs = glob(["*.h"]),
deps = [
- "//extlibs/er_force_sim/src/core:core_qt",
- "//extlibs/er_force_sim/src/protobuf:protobuf_qt",
+ "//extlibs/er_force_sim/src/core",
+ "//extlibs/er_force_sim/src/protobuf",
"//proto:ssl_simulation_cc_proto",
"//shared:constants",
"@bullet",
- "@qt//:qt_core",
- "@qt//:qt_gui",
- "@qt//:qt_widgets",
],
- #linkstatic = True,
alwayslink = True,
)
diff --git a/src/extlibs/er_force_sim/src/amun/simulator/erroraggregator.cpp b/src/extlibs/er_force_sim/src/amun/simulator/erroraggregator.cpp
deleted file mode 100644
index 850e63c24d..0000000000
--- a/src/extlibs/er_force_sim/src/amun/simulator/erroraggregator.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/****************************************************************************
- * Copyright 2021 Tobias Heineken *
- * Robotics Erlangen e.V. *
- * http://www.robotics-erlangen.de/ *
- * info@robotics-erlangen.de *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see . *
- ***************************************************************************/
-
-#include "erroraggregator.h"
-
-#include
-
-#include "simulator.h"
-
-using namespace camun::simulator;
-
-void ErrorAggregator::aggregate(SSLSimError error, ErrorSource source)
-{
- m_data[source].push_back(std::move(error));
-}
-
-QList ErrorAggregator::getAggregates(ErrorSource source)
-{
- QList &ref = m_data[source];
- QList out = ref;
- ref.clear();
- return out;
-}
diff --git a/src/extlibs/er_force_sim/src/amun/simulator/erroraggregator.h b/src/extlibs/er_force_sim/src/amun/simulator/erroraggregator.h
deleted file mode 100644
index 7f10d3e39d..0000000000
--- a/src/extlibs/er_force_sim/src/amun/simulator/erroraggregator.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/****************************************************************************
- * Copyright 2021 Tobias Heineken *
- * Robotics Erlangen e.V. *
- * http://www.robotics-erlangen.de/ *
- * info@robotics-erlangen.de *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see . *
- ***************************************************************************/
-
-#ifndef SIM_AGGREGATOR_H
-#define SIM_AGGREGATOR_H
-#include
-#include
-
-#include "extlibs/er_force_sim/src/protobuf/sslsim.h"
-
-namespace camun
-{
- namespace simulator
- {
- enum class ErrorSource;
- class ErrorAggregator : public QObject
- {
- Q_OBJECT
- public:
- ErrorAggregator(QObject* parent) : QObject(parent) {}
-
- public slots:
- void aggregate(SSLSimError eror, ErrorSource e);
-
- public:
- QList getAggregates(ErrorSource e);
-
- private:
- QMap> m_data;
- };
- } // namespace simulator
-} // namespace camun
-#endif
diff --git a/src/extlibs/er_force_sim/src/amun/simulator/mesh.cpp b/src/extlibs/er_force_sim/src/amun/simulator/mesh.cpp
deleted file mode 100644
index 599090fe94..0000000000
--- a/src/extlibs/er_force_sim/src/amun/simulator/mesh.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/***************************************************************************
- * Copyright 2015 Michael Eischer, Philipp Nordhus *
- * Robotics Erlangen e.V. *
- * http://www.robotics-erlangen.de/ *
- * info@robotics-erlangen.de *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see . *
- ***************************************************************************/
-
-#include "mesh.h"
-
-#include
-
-using namespace camun::simulator;
-
-/*!
- * \class Mesh
- * \ingroup simulator
- * \brief A 3D mesh
- */
-
-Mesh::Mesh(float radius, float height, float angle, float holeSize, float boxHeight)
- : m_radius(radius), m_height(height), m_angle(angle), m_holeSize(holeSize)
-{
- const float frontPlateLength = std::sin(angle / 2.0f) * radius;
- const float frontPlatePos = radius * std::cos(angle / 2.0f);
- const float holePlatePos = frontPlatePos - holeSize;
- const float outerAngle = std::acos(holePlatePos / radius) * 2;
- const float angleDiff = (outerAngle - angle) / 2.0f;
- const float halfOuterAngle = outerAngle / 2.0f;
- const float outerAngleStart = halfOuterAngle + M_PI_2;
- const float outerAngleStop = 2.0f * M_PI - halfOuterAngle + M_PI_2;
- addRobotCover(20, outerAngleStart, outerAngleStop);
-
- // right pillar
- addRobotCover(5, outerAngleStart - angleDiff, outerAngleStart);
- m_hull.back().append(QVector3D(-frontPlateLength, holePlatePos, m_height / 2.0f));
- m_hull.back().append(QVector3D(-frontPlateLength, holePlatePos, -m_height / 2.0f));
-
- // left pillar
- addRobotCover(5, outerAngleStop, outerAngleStop + angleDiff);
- m_hull.back().append(QVector3D(frontPlateLength, holePlatePos, m_height / 2.0f));
- m_hull.back().append(QVector3D(frontPlateLength, holePlatePos, -m_height / 2.0f));
-
- // the remaining box
- QList boxPart;
- boxPart.append(QVector3D(frontPlateLength, holePlatePos, m_height / 2.0f));
- boxPart.append(QVector3D(-frontPlateLength, holePlatePos, m_height / 2.0f));
- boxPart.append(
- QVector3D(frontPlateLength, holePlatePos, -m_height / 2.0f + boxHeight));
- boxPart.append(
- QVector3D(-frontPlateLength, holePlatePos, -m_height / 2.0f + boxHeight));
- boxPart.append(QVector3D(frontPlateLength, frontPlatePos, m_height / 2.0f));
- boxPart.append(QVector3D(-frontPlateLength, frontPlatePos, m_height / 2.0f));
- boxPart.append(
- QVector3D(frontPlateLength, frontPlatePos, -m_height / 2.0f + boxHeight));
- boxPart.append(
- QVector3D(-frontPlateLength, frontPlatePos, -m_height / 2.0f + boxHeight));
- m_hull.append(boxPart);
-}
-
-/*!
- * \brief Adds triangles for the outer hull
- * \param radius Radius of the robot
- * \param height Height of the robot
- * \param num Number of segments
- * \param angle Angle of the hull start
- * \param angleStep Step size in rad
- */
-void Mesh::addRobotCover(uint num, float startAngle, float endAngle)
-{
- QList covers;
- float angle = startAngle;
- float angleStep = (endAngle - startAngle) / num;
- for (uint i = 0; i <= num; i++)
- {
- covers.append(
- QVector3D(m_radius * cos(angle), m_radius * sin(angle), m_height / 2.0f));
- covers.append(
- QVector3D(m_radius * cos(angle), m_radius * sin(angle), -m_height / 2.0f));
-
- angle += angleStep;
- }
- m_hull.append(covers);
-}
diff --git a/src/extlibs/er_force_sim/src/amun/simulator/mesh.h b/src/extlibs/er_force_sim/src/amun/simulator/mesh.h
deleted file mode 100644
index e25ad2c019..0000000000
--- a/src/extlibs/er_force_sim/src/amun/simulator/mesh.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/***************************************************************************
- * Copyright 2015 Michael Eischer, Philipp Nordhus *
- * Robotics Erlangen e.V. *
- * http://www.robotics-erlangen.de/ *
- * info@robotics-erlangen.de *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see . *
- ***************************************************************************/
-
-#ifndef MESH_H
-#define MESH_H
-
-#include
-#include
-#include
-#include
-
-namespace camun
-{
- namespace simulator
- {
- class Mesh;
- }
-} // namespace camun
-
-class camun::simulator::Mesh
-{
- public:
- Mesh(float radius, float height, float angle, float holeSize, float boxHeight);
- void createRobotMeshes(float radius, float height, float angle);
- const QList> &hull() const
- {
- return m_hull;
- }
-
- private:
- void addRobotCover(uint num, float startAngle, float endAngle);
- void addSidePart(uint num, float angleStart, float angleStop, bool right);
-
- private:
- QList> m_hull;
-
- const float m_radius;
- const float m_height;
- const float m_angle;
- const float m_holeSize;
-};
-
-#endif // MESH_H
diff --git a/src/extlibs/er_force_sim/src/amun/simulator/robotmesh.cpp b/src/extlibs/er_force_sim/src/amun/simulator/robotmesh.cpp
new file mode 100644
index 0000000000..d06d66390c
--- /dev/null
+++ b/src/extlibs/er_force_sim/src/amun/simulator/robotmesh.cpp
@@ -0,0 +1,135 @@
+/***************************************************************************
+ * Copyright 2015 Michael Eischer, Philipp Nordhus *
+ * Robotics Erlangen e.V. *
+ * http://www.robotics-erlangen.de/ *
+ * info@robotics-erlangen.de *
+ * *
+ * This program is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 3 of the License, or *
+ * any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
+ ***************************************************************************/
+
+#include "robotmesh.h"
+
+#include
+
+using namespace camun::simulator;
+
+static std::vector> generateRobotShellPoints(
+ unsigned int numSegments, float startAngle, float endAngle, float radius,
+ float height)
+{
+ std::vector> points;
+
+ float angle = startAngle;
+ const float angleStep = (endAngle - startAngle) / numSegments;
+
+ for (unsigned int i = 0; i <= numSegments; ++i)
+ {
+ const float x = radius * std::cos(angle);
+ const float y = radius * std::sin(angle);
+
+ points.emplace_back(x, y, height / 2.0);
+ points.emplace_back(x, y, -height / 2.0);
+
+ angle += angleStep;
+ }
+
+ return points;
+}
+
+std::vector>>
+camun::simulator::createRobotMesh(float radius, float height, float angle,
+ float holeDepth, float holeHeight)
+{
+ static constexpr unsigned int NUM_SEGMENTS_HULL = 20;
+ static constexpr unsigned int NUM_SEGMENTS_PILLAR = 5;
+
+ // Diagram of robot (top view)
+ //
+ // ┌────────┬────frontPlatePos
+ // ┌───┬─────────holePlatePos
+ // ┌────┬────holeDepth
+ // , - ~ - ,
+ // , ' . ' ,
+ // , . .| ─┐
+ // , . . | │
+ // , .\. | │
+ // , + )─┐ | ├─frontPlateLength
+ // , `/` │ | │
+ // , │ │' | │
+ // , │` │ .| │
+ // , │ `│ , ' ─┘
+ // ' - , _│, │'
+ // │ └─angle
+ // └────angleDiff
+ // outerAngle = angle + angleDiff + angleDiff
+ //
+ const float frontPlateLength = std::sin(angle / 2.0) * radius;
+ const float frontPlatePos = radius * std::cos(angle / 2.0);
+ const float holePlatePos = frontPlatePos - holeDepth;
+ const float outerAngle = std::acos(holePlatePos / radius) * 2;
+ const float angleDiff = (outerAngle - angle) / 2.0;
+ const float halfOuterAngle = outerAngle / 2.0;
+ const float outerAngleStart = halfOuterAngle + M_PI_2;
+ const float outerAngleStop = 2.0 * M_PI - halfOuterAngle + M_PI_2;
+
+ std::vector>> meshParts;
+
+ // Parts of robot (top view)
+ //
+ // , - ~ - , Right pillar
+ // , ' | ' ,
+ // , ├────┐
+ // , | |
+ // , | |
+ // , Main hull | Front plate and dribbler hole
+ // , | |
+ // , | |
+ // , ├────┘
+ // , | .'
+ // ' - , _ , ' Left pillar
+ //
+
+ // Main hull
+ meshParts.push_back(generateRobotShellPoints(NUM_SEGMENTS_HULL, outerAngleStart,
+ outerAngleStop, radius, height));
+
+ // Left pillar
+ auto leftPillar = generateRobotShellPoints(
+ NUM_SEGMENTS_PILLAR, outerAngleStop, outerAngleStop + angleDiff, radius, height);
+ leftPillar.emplace_back(frontPlateLength, holePlatePos, height / 2.0);
+ leftPillar.emplace_back(frontPlateLength, holePlatePos, -height / 2.0);
+ meshParts.push_back(leftPillar);
+
+ // Right pillar
+ auto rightPillar =
+ generateRobotShellPoints(NUM_SEGMENTS_PILLAR, outerAngleStart - angleDiff,
+ outerAngleStart, radius, height);
+ rightPillar.emplace_back(-frontPlateLength, holePlatePos, height / 2.0);
+ rightPillar.emplace_back(-frontPlateLength, holePlatePos, -height / 2.0);
+ meshParts.push_back(rightPillar);
+
+ // The remaining front plate and dribbler "hole"
+ meshParts.push_back({
+ {frontPlateLength, holePlatePos, height / 2.0},
+ {-frontPlateLength, holePlatePos, height / 2.0},
+ {frontPlateLength, holePlatePos, -height / 2.0 + holeHeight},
+ {-frontPlateLength, holePlatePos, -height / 2.0 + holeHeight},
+ {frontPlateLength, frontPlatePos, height / 2.0},
+ {-frontPlateLength, frontPlatePos, height / 2.0},
+ {frontPlateLength, frontPlatePos, -height / 2.0 + holeHeight},
+ {-frontPlateLength, frontPlatePos, -height / 2.0 + holeHeight},
+ });
+
+ return meshParts;
+}
diff --git a/src/extlibs/er_force_sim/src/protobuf/sslsim.h b/src/extlibs/er_force_sim/src/amun/simulator/robotmesh.h
similarity index 76%
rename from src/extlibs/er_force_sim/src/protobuf/sslsim.h
rename to src/extlibs/er_force_sim/src/amun/simulator/robotmesh.h
index 8bdc8aac12..3670e3f81e 100644
--- a/src/extlibs/er_force_sim/src/protobuf/sslsim.h
+++ b/src/extlibs/er_force_sim/src/amun/simulator/robotmesh.h
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright 2021 Tobias Heineken *
+ * Copyright 2015 Michael Eischer, Philipp Nordhus *
* Robotics Erlangen e.V. *
* http://www.robotics-erlangen.de/ *
* info@robotics-erlangen.de *
@@ -18,14 +18,19 @@
* along with this program. If not, see . *
***************************************************************************/
-#ifndef PB_SSLSIM_H
-#define PB_SSLSIM_H
+#ifndef ROBOTMESH_H
+#define ROBOTMESH_H
-#include
+#include
+#include
-#include "extlibs/er_force_sim/src/protobuf/ssl_simulation_error.pb.h"
-#include "extlibs/er_force_sim/src/protobuf/ssl_simulation_robot_control.pb.h"
+namespace camun
+{
+ namespace simulator
+ {
+ std::vector>> createRobotMesh(
+ float radius, float height, float angle, float holeDepth, float holeHeight);
+ } // namespace simulator
+} // namespace camun
-typedef QSharedPointer SSLSimRobotControl;
-typedef QSharedPointer SSLSimError;
-#endif
+#endif // ROBOTMESH_H
diff --git a/src/extlibs/er_force_sim/src/amun/simulator/simball.cpp b/src/extlibs/er_force_sim/src/amun/simulator/simball.cpp
index 054a1d8b24..81c40e84c3 100644
--- a/src/extlibs/er_force_sim/src/amun/simulator/simball.cpp
+++ b/src/extlibs/er_force_sim/src/amun/simulator/simball.cpp
@@ -20,30 +20,26 @@
#include "simball.h"
-#include
#include
#include "extlibs/er_force_sim/src/core/coordinates.h"
-#include "extlibs/er_force_sim/src/core/rng.h"
#include "extlibs/er_force_sim/src/core/vector.h"
-#include "proto/ssl_vision_detection.pb.h"
#include "simulator.h"
using namespace camun::simulator;
-SimBall::SimBall(RNG *rng, btDiscreteDynamicsWorld *world)
- : m_rng(rng),
- m_world(world),
- current_ball_state(STATIONARY),
- set_transition_speed(true),
- rolling_speed(-1.0f)
+SimBall::SimBall(std::shared_ptr world)
+ : m_world(world),
+ m_rolling_speed(-1.0f),
+ m_set_transition_speed(true),
+ m_current_ball_state(STATIONARY)
{
// see http://robocup.mi.fu-berlin.de/buch/rolling.pdf for correct modelling
- m_sphere =
- new btSphereShape(static_cast(BALL_MAX_RADIUS_METERS) * SIMULATOR_SCALE);
+ m_sphere = std::make_unique(
+ static_cast(BALL_MAX_RADIUS_METERS) * SIMULATOR_SCALE);
- btVector3 localInertia(0, 0, 0);
// FIXME measure inertia coefficient
+ btVector3 localInertia(0, 0, 0);
m_sphere->calculateLocalInertia(BALL_MASS_KG, localInertia);
btTransform startWorldTransform;
@@ -51,30 +47,28 @@ SimBall::SimBall(RNG *rng, btDiscreteDynamicsWorld *world)
startWorldTransform.setOrigin(
btVector3(0.0f, 0.0f, static_cast(BALL_MAX_RADIUS_METERS)) *
SIMULATOR_SCALE);
- m_motionState = new btDefaultMotionState(startWorldTransform);
+ m_motionState = std::make_unique(startWorldTransform);
- btRigidBody::btRigidBodyConstructionInfo rbInfo(BALL_MASS_KG, m_motionState, m_sphere,
- localInertia);
+ btRigidBody::btRigidBodyConstructionInfo rbInfo(BALL_MASS_KG, m_motionState.get(),
+ m_sphere.get(), localInertia);
// parameters seem to be ignored...
- m_body = new btRigidBody(rbInfo);
- // see simulator.cpp
- // TODO (#2512): Check these values with real life
+ m_body = std::make_unique(rbInfo);
+
+ // See simulator.h
m_body->setRestitution(BALL_RESTITUTION);
m_body->setFriction(BALL_SLIDING_FRICTION_NEWTONS);
// \mu_r = -a / g = 0.0357 (while rolling)
// rollingFriction in bullet is too unstable to be useful
// use custom implementation in begin()
- m_world->addRigidBody(m_body);
+
+ m_world->addRigidBody(m_body.get());
}
SimBall::~SimBall()
{
- m_world->removeRigidBody(m_body);
- delete m_body;
- delete m_sphere;
- delete m_motionState;
+ m_world->removeRigidBody(m_body.get());
}
void SimBall::begin(bool robot_collision)
@@ -86,48 +80,47 @@ void SimBall::begin(bool robot_collision)
{ // ball is on the ground
bool is_stationary =
velocity.length() < STATIONARY_BALL_SPEED_METERS_PER_SECOND * SIMULATOR_SCALE;
- bool should_roll = velocity.length() < rolling_speed * SIMULATOR_SCALE;
+ bool should_roll = velocity.length() < m_rolling_speed * SIMULATOR_SCALE;
if (robot_collision)
{
- current_ball_state = ROBOT_COLLISION;
+ m_current_ball_state = ROBOT_COLLISION;
}
else if (is_stationary)
{
- current_ball_state = STATIONARY;
+ m_current_ball_state = STATIONARY;
}
- else if ((current_ball_state == SLIDING && should_roll) ||
- current_ball_state == ROLLING)
+ else if ((m_current_ball_state == SLIDING && should_roll) ||
+ m_current_ball_state == ROLLING)
{
- current_ball_state = ROLLING;
+ m_current_ball_state = ROLLING;
}
else
{
- current_ball_state = SLIDING;
+ m_current_ball_state = SLIDING;
}
- switch (current_ball_state)
+ switch (m_current_ball_state)
{
case STATIONARY:
m_body->setLinearVelocity(btVector3(0, 0, 0));
m_body->setFriction(BALL_SLIDING_FRICTION_NEWTONS);
- set_transition_speed = true;
+ m_set_transition_speed = true;
break;
case ROBOT_COLLISION:
m_body->setFriction(BALL_SLIDING_FRICTION_NEWTONS);
- set_transition_speed = true;
+ m_set_transition_speed = true;
break;
case SLIDING:
m_body->setFriction(BALL_SLIDING_FRICTION_NEWTONS);
- if (set_transition_speed)
+ if (m_set_transition_speed)
{
- rolling_speed =
+ m_rolling_speed =
FRICTION_TRANSITION_FACTOR * velocity.length() / SIMULATOR_SCALE;
}
- set_transition_speed = false;
+ m_set_transition_speed = false;
break;
case ROLLING:
-
// just apply rolling friction, normal friction is somehow handled by
// bullet
const btScalar rollingDeceleration =
@@ -139,54 +132,32 @@ void SimBall::begin(bool robot_collision)
SUB_TIMESTEP);
m_body->setFriction(0.0f);
- set_transition_speed = false;
+ m_set_transition_speed = false;
break;
}
}
- bool moveCommand = false;
- auto sendPartialCoordError = [this](const char *msg) {
- SSLSimError error{new sslsim::SimulatorError};
- error->set_code("PARTIAL_COORD");
- std::string message = "Partial coordinates are not implemented yet";
- error->set_message(message + msg);
- emit this->sendSSLSimError(error, ErrorSource::CONFIG);
- };
- if (m_move.has_x())
+ if (m_move.has_x() != m_move.has_y())
{
- if (!m_move.has_y())
- {
- sendPartialCoordError(": position ball");
- return;
- }
- moveCommand = true;
+ std::cerr << "Partial coordinates are not implemented yet: ball position"
+ << std::endl;
+ return;
}
- else if (m_move.has_y() || m_move.has_z())
+
+ if (m_move.has_vx() != m_move.has_vy())
{
- sendPartialCoordError(": position ball (not x)");
+ std::cerr << "Partial coordinates are not implemented yet: ball velocity"
+ << std::endl;
return;
}
- if (m_move.has_vx())
+ if (m_move.by_force() && (m_move.vx() != 0 || m_move.vy() != 0 || m_move.vz() != 0))
{
- if (!m_move.has_vy())
- {
- sendPartialCoordError(": velocity ball");
- return;
- }
- if (m_move.by_force() && (m_move.vx() != 0 || m_move.vy() != 0 ||
- (m_move.has_vz() && m_move.vz() != 0)))
- {
- SSLSimError error{new sslsim::SimulatorError};
- error->set_code("VELOCITY_FORCE");
- error->set_message("Velocities != 0 and by_force are incompatible");
- emit sendSSLSimError(error, ErrorSource::CONFIG);
- return;
- }
- moveCommand = true;
+ std::cerr << "Velocities != 0 and by_force are incompatible" << std::endl;
+ return;
}
- if (moveCommand)
+ if (m_move.has_x() || m_move.has_vx())
{
if (m_move.by_force())
{
@@ -232,9 +203,9 @@ void SimBall::begin(bool robot_collision)
m_body->setLinearVelocity(linVel * SIMULATOR_SCALE);
// override ballState
- current_ball_state = SLIDING;
- rolling_speed = linVel.length() * FRICTION_TRANSITION_FACTOR;
- set_transition_speed = false;
+ m_current_ball_state = SLIDING;
+ m_rolling_speed = linVel.length() * FRICTION_TRANSITION_FACTOR;
+ m_set_transition_speed = false;
m_body->setAngularVelocity(btVector3(0, 0, 0));
}
@@ -328,7 +299,7 @@ static float positionOfVisiblePixels(btVector3 &p, const btVector3 &simulatorBal
return static_cast(cameraHitCounter) / static_cast(maxHits);
}
-bool SimBall::update(SSLProto::SSL_DetectionBall *ball, float stddev, float stddevArea,
+bool SimBall::update(SSLProto::SSL_DetectionBall &ball, float stddev, float stddevArea,
const btVector3 &cameraPosition, bool enableInvisibleBall,
float visibilityThreshold, btVector3 positionOffset)
{
@@ -340,15 +311,15 @@ bool SimBall::update(SSLProto::SSL_DetectionBall *ball, float stddev, float stdd
enableInvisibleBall, visibilityThreshold, positionOffset);
}
-bool SimBall::addDetection(SSLProto::SSL_DetectionBall *ball, btVector3 pos, float stddev,
+bool SimBall::addDetection(SSLProto::SSL_DetectionBall &ball, btVector3 pos, float stddev,
float stddevArea, const btVector3 &cameraPosition,
bool enableInvisibleBall, float visibilityThreshold,
btVector3 positionOffset)
{
// setup ssl-vision ball detection
- ball->set_confidence(1.0f);
- ball->set_pixel_x(0.0f);
- ball->set_pixel_y(0.0f);
+ ball.set_confidence(1.0f);
+ ball.set_pixel_x(0.0f);
+ ball.set_pixel_y(0.0f);
btTransform transform;
m_motionState->getWorldTransform(transform);
@@ -365,7 +336,7 @@ bool SimBall::addDetection(SSLProto::SSL_DetectionBall *ball, btVector3 pos, flo
{
// if the visibility is lower than the threshold the ball disappears
visibility = positionOfVisiblePixels(pos, transform.getOrigin(),
- simulatorCameraPosition, m_world);
+ simulatorCameraPosition, m_world.get());
if (visibility < visibilityThreshold)
{
return false;
@@ -398,21 +369,15 @@ bool SimBall::addDetection(SSLProto::SSL_DetectionBall *ball, btVector3 pos, flo
float area =
visibility *
std::max(0.0f, (basePixelArea +
- static_cast(m_rng->normal(stddevArea)) / PIXEL_PER_AREA));
- ball->set_area(area * PIXEL_PER_AREA);
-
- // if (height > 0.1f) {
- // qDebug() << "simball" << p.x() << p.y() << height << "ttt" << ball_x <<
- // ball_y;
- // }
+ static_cast(m_rng.normal(stddevArea)) / PIXEL_PER_AREA));
+ ball.set_area(area * PIXEL_PER_AREA);
// add noise to coordinates
- // to convert from bullet coordinate system to ssl-vision rotate by 90 degree
- // ccw
- const ErForceVector noise = m_rng->normalVector(stddev);
- coordinates::toVision(ErForceVector(modX, modY) + noise, *ball);
+ // to convert from bullet coordinate system to ssl-vision rotate by 90 degree ccw
+ const ErForceVector noise = m_rng.normalVector(stddev);
+ coordinates::toVision(ErForceVector(modX, modY) + noise, ball);
- ball->set_z(modZ * 1000); // modZ is in kilometres, need to convert to metres
+ ball.set_z(modZ * 1000); // modZ is in kilometres, need to convert to metres
return true;
}
@@ -433,21 +398,21 @@ btVector3 SimBall::speed() const
return m_body->getLinearVelocity();
}
-void SimBall::writeBallState(world::SimBall *ball) const
+void SimBall::writeBallState(world::SimBall &ball) const
{
const btVector3 ballPosition =
m_body->getWorldTransform().getOrigin() / SIMULATOR_SCALE;
- ball->set_p_x(ballPosition.getX());
- ball->set_p_y(ballPosition.getY());
- ball->set_p_z(ballPosition.getZ());
+ ball.set_p_x(ballPosition.getX());
+ ball.set_p_y(ballPosition.getY());
+ ball.set_p_z(ballPosition.getZ());
const btVector3 ballSpeed = speed() / SIMULATOR_SCALE;
- ball->set_v_x(ballSpeed.getX());
- ball->set_v_y(ballSpeed.getY());
- ball->set_v_z(ballSpeed.getZ());
+ ball.set_v_x(ballSpeed.getX());
+ ball.set_v_y(ballSpeed.getY());
+ ball.set_v_z(ballSpeed.getZ());
const btVector3 angularVelocity = m_body->getAngularVelocity();
- ball->set_angular_x(angularVelocity.x());
- ball->set_angular_y(angularVelocity.y());
- ball->set_angular_z(angularVelocity.z());
+ ball.set_angular_x(angularVelocity.x());
+ ball.set_angular_y(angularVelocity.y());
+ ball.set_angular_z(angularVelocity.z());
}
void SimBall::restoreState(const world::SimBall &ball)
@@ -479,8 +444,4 @@ void SimBall::kick(const btVector3 &power)
{
m_body->activate();
m_body->applyCentralForce(power);
- // btTransform transform;
- // m_motionState->getWorldTransform(transform);
- // const btVector3 p = transform.getOrigin() / SIMULATOR_SCALE;
- // qDebug() << "kick at" << p.x() << p.y();
}
diff --git a/src/extlibs/er_force_sim/src/amun/simulator/simball.h b/src/extlibs/er_force_sim/src/amun/simulator/simball.h
index a7000400a6..1d9022c837 100644
--- a/src/extlibs/er_force_sim/src/amun/simulator/simball.h
+++ b/src/extlibs/er_force_sim/src/amun/simulator/simball.h
@@ -23,78 +23,83 @@
#include
-#include
-
+#include "extlibs/er_force_sim/src/core/rng.h"
#include "extlibs/er_force_sim/src/protobuf/command.pb.h"
-#include "extlibs/er_force_sim/src/protobuf/sslsim.h"
+#include "extlibs/er_force_sim/src/protobuf/world.pb.h"
+#include "proto/ssl_vision_detection.pb.h"
#include "shared/constants.h"
-#include "simfield.h"
-
-class RNG;
-namespace SSLProto
-{
- class SSL_DetectionBall;
-}
namespace camun
{
namespace simulator
{
class SimBall;
- enum class ErrorSource;
} // namespace simulator
} // namespace camun
-class camun::simulator::SimBall : public QObject
+class camun::simulator::SimBall
{
- Q_OBJECT
public:
- SimBall(RNG *rng, btDiscreteDynamicsWorld *world);
+ SimBall(std::shared_ptr world);
~SimBall();
- SimBall(const SimBall &) = delete;
- SimBall &operator=(const SimBall &) = delete;
-
- signals:
- void sendSSLSimError(const SSLSimError &error, ErrorSource s);
public:
/**
- * processes velocity and forces to be applied on the ball
- * @param robot_collision whether the ball collides with a robot in this simulation
- * tick
+ * Processes velocity and forces to be applied on the ball
+ *
+ * @param robot_collision whether the ball collides with a robot in
+ * this simulation tick
*/
void begin(bool robot_collision);
- bool update(SSLProto::SSL_DetectionBall *ball, float stddev, float stddevArea,
+
+ bool update(SSLProto::SSL_DetectionBall &ball, float stddev, float stddevArea,
const btVector3 &cameraPosition, bool enableInvisibleBall,
float visibilityThreshold, btVector3 positionOffset);
+
void move(const sslsim::TeleportBall &ball);
+
void kick(const btVector3 &power);
- // returns the ball position projected onto the floor (z component is not included)
+
+ /**
+ * Returns the ball's position projected onto the floor (z component is not included)
+ *
+ * @return the ball position
+ */
btVector3 position() const;
+
+ /**
+ * Returns the ball's linear velocity
+ *
+ * @return the ball velocity
+ */
btVector3 speed() const;
- void writeBallState(world::SimBall *ball) const;
+
+ void writeBallState(world::SimBall &ball) const;
+
void restoreState(const world::SimBall &ball);
+
btRigidBody *body() const
{
- return m_body;
+ return m_body.get();
}
+
bool isInvalid() const;
// can be used to add ball mis-detections
- bool addDetection(SSLProto::SSL_DetectionBall *ball, btVector3 pos, float stddev,
+ bool addDetection(SSLProto::SSL_DetectionBall &ball, btVector3 pos, float stddev,
float stddevArea, const btVector3 &cameraPosition,
bool enableInvisibleBall, float visibilityThreshold,
btVector3 positionOffset);
private:
- RNG *m_rng;
- btDiscreteDynamicsWorld *m_world;
- btCollisionShape *m_sphere;
- btRigidBody *m_body;
- btMotionState *m_motionState;
+ RNG m_rng;
+ std::shared_ptr m_world;
+ std::unique_ptr m_sphere;
+ std::unique_ptr m_body;
+ std::unique_ptr m_motionState;
sslsim::TeleportBall m_move;
- double rolling_speed;
- bool set_transition_speed;
+ double m_rolling_speed;
+ bool m_set_transition_speed;
enum BallState
{
@@ -103,7 +108,8 @@ class camun::simulator::SimBall : public QObject
SLIDING,
ROLLING
};
- BallState current_ball_state;
+
+ BallState m_current_ball_state;
};
#endif // SIMBALL_H
diff --git a/src/extlibs/er_force_sim/src/amun/simulator/simfield.cpp b/src/extlibs/er_force_sim/src/amun/simulator/simfield.cpp
index 78b4e9e510..38acbaff55 100644
--- a/src/extlibs/er_force_sim/src/amun/simulator/simfield.cpp
+++ b/src/extlibs/er_force_sim/src/amun/simulator/simfield.cpp
@@ -24,109 +24,99 @@
using namespace camun::simulator;
-SimField::SimField(btDiscreteDynamicsWorld *world, const world::Geometry &geometry)
+SimField::SimField(std::shared_ptr world,
+ const world::Geometry &geometry)
: m_world(world)
{
const float totalWidth = geometry.field_width() / 2.0f + geometry.boundary_width();
const float totalHeight = geometry.field_height() / 2.0f + geometry.boundary_width();
- // upper boundary
- const float roomHeight = 8.0f;
- const float height = geometry.field_height() / 2.0f - geometry.line_width();
+ const float roomHeight = 8.0f; // Upper boundary of "room" that the field lives in
+ const float height = geometry.field_height() / 2.0f - geometry.line_width();
const float goalWidthHalf = geometry.goal_width() / 2.0f + geometry.goal_wall_width();
const float goalHeightHalf = geometry.goal_height() / 2.0f;
const float goalDepth = geometry.goal_depth() + geometry.goal_wall_width();
const float goalDepthHalf = goalDepth / 2.0f;
const float goalWallHalf = geometry.goal_wall_width() / 2.0f;
- // obstacle prototypes
- m_plane = new btStaticPlaneShape(btVector3(0, 0, 1), 0);
- m_goalSide = new btBoxShape(btVector3(goalWallHalf, goalDepthHalf, goalHeightHalf) *
- SIMULATOR_SCALE);
- m_goalBack = new btBoxShape(btVector3(goalWidthHalf, goalWallHalf, goalHeightHalf) *
- SIMULATOR_SCALE);
+ // Collision shapes
+ m_plane = std::make_unique(btVector3(0, 0, 1), 0);
+ m_goalSide = std::make_unique(
+ btVector3(goalWallHalf, goalDepthHalf, goalHeightHalf) * SIMULATOR_SCALE);
+ m_goalBack = std::make_unique(
+ btVector3(goalWidthHalf, goalWallHalf, goalHeightHalf) * SIMULATOR_SCALE);
- // build field cube
- // floor
- addObject(m_plane,
+ // Create the "room" that the field lives in
+ // Floor
+ addObject(m_plane.get(),
btTransform(btQuaternion(btVector3(1, 0, 0), 0),
btVector3(0, 0, 0) * SIMULATOR_SCALE),
0.56, 0.35);
- // others
- addObject(m_plane,
+ // Roof
+ addObject(m_plane.get(),
btTransform(btQuaternion(btVector3(1, 0, 0), M_PI),
btVector3(0, 0, roomHeight) * SIMULATOR_SCALE),
0.3, 0.35);
-
- addObject(m_plane,
+ // Walls
+ addObject(m_plane.get(),
btTransform(btQuaternion(btVector3(1, 0, 0), M_PI_2),
btVector3(0, totalHeight, 0) * SIMULATOR_SCALE),
0.3, 0.35);
- addObject(m_plane,
+ addObject(m_plane.get(),
btTransform(btQuaternion(btVector3(1, 0, 0), -M_PI_2),
btVector3(0, -totalHeight, 0) * SIMULATOR_SCALE),
0.3, 0.35);
-
- addObject(m_plane,
+ addObject(m_plane.get(),
btTransform(btQuaternion(btVector3(0, 1, 0), M_PI_2),
btVector3(-totalWidth, 0, 0) * SIMULATOR_SCALE),
0.3, 0.35);
- addObject(m_plane,
+ addObject(m_plane.get(),
btTransform(btQuaternion(btVector3(0, 1, 0), -M_PI_2),
btVector3(totalWidth, 0, 0) * SIMULATOR_SCALE),
0.3, 0.35);
- // create goals
- for (int goal = 0; goal < 2; goal++)
+ // Create goals
+ for (const float side : {-1.0f, 1.0f})
{
- const float side = (goal == 0) ? -1.0f : 1.0f;
- const btQuaternion rot = btQuaternion::getIdentity();
-
- addObject(
- m_goalSide,
- btTransform(rot, btVector3((goalWidthHalf - goalWallHalf),
- side * (height + goalDepthHalf), goalHeightHalf) *
- SIMULATOR_SCALE),
- 0.3, 0.5);
- addObject(
- m_goalSide,
- btTransform(rot, btVector3(-(goalWidthHalf - goalWallHalf),
- side * (height + goalDepthHalf), goalHeightHalf) *
- SIMULATOR_SCALE),
- 0.3, 0.5);
- addObject(
- m_goalBack,
- btTransform(rot, btVector3(0.0f, side * (height + goalDepth - goalWallHalf),
- goalHeightHalf) *
- SIMULATOR_SCALE),
- 0.1, 0.5);
+ addObject(m_goalSide.get(),
+ btTransform(btQuaternion::getIdentity(),
+ btVector3((goalWidthHalf - goalWallHalf),
+ side * (height + goalDepthHalf), goalHeightHalf) *
+ SIMULATOR_SCALE),
+ 0.3, 0.5);
+ addObject(m_goalSide.get(),
+ btTransform(btQuaternion::getIdentity(),
+ btVector3(-(goalWidthHalf - goalWallHalf),
+ side * (height + goalDepthHalf), goalHeightHalf) *
+ SIMULATOR_SCALE),
+ 0.3, 0.5);
+ addObject(m_goalBack.get(),
+ btTransform(btQuaternion::getIdentity(),
+ btVector3(0.0f, side * (height + goalDepth - goalWallHalf),
+ goalHeightHalf) *
+ SIMULATOR_SCALE),
+ 0.1, 0.5);
}
}
SimField::~SimField()
{
- foreach (btCollisionObject *object, m_objects)
+ for (const auto &object : m_objects)
{
- m_world->removeCollisionObject(object);
- delete object;
+ m_world->removeCollisionObject(object.get());
}
-
- delete m_goalSide;
- delete m_goalBack;
- delete m_plane;
}
void SimField::addObject(btCollisionShape *shape, const btTransform &transform,
float restitution, float friction)
{
- // create new obstacle
- btCollisionObject *object = new btCollisionObject;
+ std::unique_ptr object = std::make_unique();
+
object->setCollisionShape(shape);
- // damp ball a bit if it hits an obstacle
+ object->setWorldTransform(transform);
object->setRestitution(restitution);
- // the friction is multiplied with the colliding obstacle ones
object->setFriction(friction);
object->setRollingFriction(friction);
- object->setWorldTransform(transform);
- m_world->addCollisionObject(object);
- m_objects.append(object);
+
+ m_world->addCollisionObject(object.get());
+ m_objects.push_back(std::move(object));
}
diff --git a/src/extlibs/er_force_sim/src/amun/simulator/simfield.h b/src/extlibs/er_force_sim/src/amun/simulator/simfield.h
index 8582be8a21..b7743d2f43 100644
--- a/src/extlibs/er_force_sim/src/amun/simulator/simfield.h
+++ b/src/extlibs/er_force_sim/src/amun/simulator/simfield.h
@@ -23,8 +23,6 @@
#include
-#include
-
#include "extlibs/er_force_sim/src/protobuf/world.pb.h"
namespace camun
@@ -32,27 +30,26 @@ namespace camun
namespace simulator
{
class SimField;
- }
+ } // namespace simulator
} // namespace camun
class camun::simulator::SimField
{
public:
- SimField(btDiscreteDynamicsWorld *world, const world::Geometry &geometry);
+ SimField(std::shared_ptr world,
+ const world::Geometry &geometry);
~SimField();
- SimField(const SimField &) = delete;
- SimField &operator=(const SimField &) = delete;
private:
void addObject(btCollisionShape *shape, const btTransform &transform,
float restitution, float friction);
private:
- btDiscreteDynamicsWorld *m_world;
- btCollisionShape *m_plane;
- btCollisionShape *m_goalSide;
- btCollisionShape *m_goalBack;
- QList m_objects;
+ std::shared_ptr m_world;
+ std::unique_ptr m_plane;
+ std::unique_ptr m_goalSide;
+ std::unique_ptr m_goalBack;
+ std::vector> m_objects;
};
#endif // SIMFIELD_H
diff --git a/src/extlibs/er_force_sim/src/amun/simulator/simrobot.cpp b/src/extlibs/er_force_sim/src/amun/simulator/simrobot.cpp
index ddd3767992..571dfd38e9 100644
--- a/src/extlibs/er_force_sim/src/amun/simulator/simrobot.cpp
+++ b/src/extlibs/er_force_sim/src/amun/simulator/simrobot.cpp
@@ -20,57 +20,51 @@
#include "simrobot.h"
+#include
#include
#include "extlibs/er_force_sim/src/core/coordinates.h"
-#include "extlibs/er_force_sim/src/core/rng.h"
-#include "mesh.h"
-#include "proto/ssl_vision_detection.pb.h"
-#include "simball.h"
+#include "robotmesh.h"
#include "simulator.h"
using namespace camun::simulator;
const float MAX_SPEED = 1000;
-float boundSpeed(float speed)
-{
- return qBound(-MAX_SPEED, speed, MAX_SPEED);
-}
-
-SimRobot::SimRobot(RNG *rng, const robot::Specs &specs, btDiscreteDynamicsWorld *world,
- const btVector3 &pos, float dir)
- : m_rng(rng),
- m_specs(specs),
+SimRobot::SimRobot(const robot::Specs &specs,
+ std::shared_ptr world, const btVector3 &pos,
+ float dir)
+ : m_specs(specs),
m_world(world),
m_charge(false),
m_isCharged(false),
m_inStandby(false),
m_shootTime(0.0),
m_commandTime(0.0),
- error_sum_v_s(0),
- error_sum_v_f(0),
- error_sum_omega(0)
+ m_error_sum_v_s(0),
+ m_error_sum_v_f(0),
+ m_error_sum_omega(0)
{
- btCompoundShape *wholeShape = new btCompoundShape;
+ std::unique_ptr wholeShape = std::make_unique();
btTransform robotShapeTransform;
robotShapeTransform.setIdentity();
// subtract collision margin from dimensions
- Mesh mesh(m_specs.radius() - COLLISION_MARGIN / SIMULATOR_SCALE,
- m_specs.height() - 2 * COLLISION_MARGIN / SIMULATOR_SCALE, m_specs.angle(),
- 0.04f, m_specs.dribbler_height() + 0.02f);
- for (const QList &hullPart : mesh.hull())
+ auto mesh =
+ createRobotMesh(m_specs.radius() - COLLISION_MARGIN / SIMULATOR_SCALE,
+ m_specs.height() - 2 * COLLISION_MARGIN / SIMULATOR_SCALE,
+ m_specs.angle(), 0.04f, m_specs.dribbler_height() + 0.02f);
+ for (const auto &hullPart : mesh)
{
- btConvexHullShape *hullPartShape = new btConvexHullShape;
- m_shapes.append(hullPartShape);
- for (const QVector3D &v : hullPart)
+ std::unique_ptr hullPartShape =
+ std::make_unique();
+ for (const auto &[x, y, z] : hullPart)
{
- hullPartShape->addPoint(btVector3(v.x(), v.y(), v.z()) * SIMULATOR_SCALE);
+ hullPartShape->addPoint(btVector3(x, y, z) * SIMULATOR_SCALE);
}
- wholeShape->addChildShape(robotShapeTransform, hullPartShape);
+ wholeShape->addChildShape(robotShapeTransform, hullPartShape.get());
+ m_shapes.push_back(std::move(hullPartShape));
}
- m_shapes.append(wholeShape);
btTransform startWorldTransform;
startWorldTransform.setIdentity();
@@ -78,24 +72,25 @@ SimRobot::SimRobot(RNG *rng, const robot::Specs &specs, btDiscreteDynamicsWorld
SIMULATOR_SCALE);
startWorldTransform.setOrigin(robotBasePos);
startWorldTransform.setRotation(btQuaternion(btVector3(0, 0, 1), dir - M_PI_2));
- m_motionState = new btDefaultMotionState(startWorldTransform);
+ m_motionState = std::make_unique(startWorldTransform);
// set robot dynamics and move to start position
btVector3 localInertia(0, 0, 0);
const float robotMassProportion = 49.0f / 50.0f;
wholeShape->calculateLocalInertia(robotMassProportion * m_specs.mass(), localInertia);
- btRigidBody::btRigidBodyConstructionInfo rbInfo(
- robotMassProportion * m_specs.mass(), m_motionState, wholeShape, localInertia);
+ btRigidBody::btRigidBodyConstructionInfo rbInfo(robotMassProportion * m_specs.mass(),
+ m_motionState.get(), wholeShape.get(),
+ localInertia);
- m_body = new btRigidBody(rbInfo);
+ m_body = std::make_unique(rbInfo);
// see simulator.cpp
m_body->setRestitution(0.6f);
m_body->setFriction(0.22f);
- m_world->addRigidBody(m_body);
+ m_world->addRigidBody(m_body.get());
- btCylinderShape *dribblerShape = new btCylinderShapeX(
+ std::unique_ptr dribblerShape = std::make_unique(
btVector3(m_specs.dribbler_width() / 2.0f, 0.007f, 0.007f) * SIMULATOR_SCALE);
- m_shapes.append(dribblerShape);
+
// WARNING: hack, instead of 0.02 should be the dribbler height
// the ball seems to get instable if the dribbler is at correct height
// possibly the ball gets 'sucked' onto the robot
@@ -111,15 +106,14 @@ SimRobot::SimRobot(RNG *rng, const robot::Specs &specs, btDiscreteDynamicsWorld
dribblerShape->calculateLocalInertia((1 - robotMassProportion) * m_specs.mass(),
dribblerInertia);
btRigidBody::btRigidBodyConstructionInfo rbDribInfo(
- (1 - robotMassProportion) * m_specs.mass(), nullptr, dribblerShape,
+ (1 - robotMassProportion) * m_specs.mass(), nullptr, dribblerShape.get(),
dribblerInertia);
rbDribInfo.m_startWorldTransform = dribblerStartTransform;
- btRigidBody *dribblerBody = new btRigidBody(rbDribInfo);
- dribblerBody->setRestitution(0.2f);
- dribblerBody->setFriction(1.5f);
- m_dribblerBody = dribblerBody;
- m_world->addRigidBody(dribblerBody);
+ m_dribblerBody = std::make_unique(rbDribInfo);
+ m_dribblerBody->setRestitution(0.2f);
+ m_dribblerBody->setFriction(1.5f);
+ m_world->addRigidBody(m_dribblerBody.get());
btTransform localA, localB;
localA.setIdentity();
@@ -127,9 +121,13 @@ SimRobot::SimRobot(RNG *rng, const robot::Specs &specs, btDiscreteDynamicsWorld
localA.setOrigin(m_dribblerCenter);
localA.setRotation(btQuaternion(btVector3(0, 1, 0), M_PI_2));
localB.setRotation(btQuaternion(btVector3(0, 1, 0), M_PI_2));
- m_dribblerConstraint = new btHingeConstraint(*m_body, *dribblerBody, localA, localB);
+ m_dribblerConstraint =
+ std::make_unique(*m_body, *m_dribblerBody, localA, localB);
m_dribblerConstraint->enableAngularMotor(false, 0, 0);
- m_world->addConstraint(m_dribblerConstraint, true);
+ m_world->addConstraint(m_dribblerConstraint.get(), true);
+
+ m_shapes.push_back(std::move(wholeShape));
+ m_shapes.push_back(std::move(dribblerShape));
}
SimRobot::~SimRobot()
@@ -138,14 +136,9 @@ SimRobot::~SimRobot()
{
m_world->removeConstraint(m_holdBallConstraint.get());
}
- m_world->removeConstraint(m_dribblerConstraint);
- m_world->removeRigidBody(m_dribblerBody);
- m_world->removeRigidBody(m_body);
- delete m_dribblerConstraint;
- delete m_body;
- delete m_dribblerBody;
- delete m_motionState;
- qDeleteAll(m_shapes);
+ m_world->removeConstraint(m_dribblerConstraint.get());
+ m_world->removeRigidBody(m_dribblerBody.get());
+ m_world->removeRigidBody(m_body.get());
}
void SimRobot::calculateDribblerMove(const btVector3 pos, const btQuaternion rot,
@@ -165,7 +158,7 @@ void SimRobot::calculateDribblerMove(const btVector3 pos, const btQuaternion rot
m_dribblerBody->setAngularVelocity(btVector3(0, 0, 0));
}
-void SimRobot::dribble(SimBall *ball, float speed)
+void SimRobot::dribble(const SimBall &ball, float speed)
{
if (m_perfectDribbler)
{
@@ -176,12 +169,12 @@ void SimRobot::dribble(SimBall *ball, float speed)
localB.setIdentity();
auto worldToRobot = m_body->getWorldTransform().inverse();
- localA.setOrigin(worldToRobot * ball->position());
+ localA.setOrigin(worldToRobot * ball.position());
localA.setRotation(btQuaternion(worldToRobot * btVector3(0, 1, 0), M_PI_2));
localB.setRotation(btQuaternion(worldToRobot * btVector3(0, 1, 0), M_PI_2));
- m_holdBallConstraint.reset(
- new btHingeConstraint(*m_body, *ball->body(), localA, localB));
+ m_holdBallConstraint = std::make_unique(
+ *m_body, *ball.body(), localA, localB);
m_world->addConstraint(m_holdBallConstraint.get(), true);
}
}
@@ -191,7 +184,7 @@ void SimRobot::dribble(SimBall *ball, float speed)
const float max_rotation_speed = 150.f / 2 / M_PI * 60;
float dribbler = speed / max_rotation_speed;
// rad/s is limited to 150
- float boundedDribbler = qBound(0.0f, dribbler, 1.0f);
+ float boundedDribbler = std::clamp(dribbler, 0.0f, 1.0f);
m_dribblerConstraint->enableAngularMotor(true, 150 * boundedDribbler,
20 * boundedDribbler);
}
@@ -217,7 +210,7 @@ void SimRobot::setDribbleMode(bool perfectDribbler)
m_perfectDribbler = perfectDribbler;
}
-void SimRobot::begin(SimBall *ball, double time)
+void SimRobot::begin(SimBall &ball, double time)
{
m_commandTime += time;
m_inStandby = false;
@@ -243,20 +236,14 @@ void SimRobot::begin(SimBall *ball, double time)
}
auto sendPartialCoordError = [this](const std::string &msg) {
- SSLSimError error{new sslsim::SimulatorError};
- error->set_code("PARTIAL_COORD");
- std::string message = "Partial coordinates are not implemented yet";
- error->set_message(message + msg);
- emit this->sendSSLSimError(error, ErrorSource::CONFIG);
+ std::cerr << "Partial coordinates are not implemented yet" << msg << std::endl;
if (!m_move.has_by_force() || !m_move.by_force())
{
m_move.Clear();
}
};
bool moveCommand = false;
- std::string message = " for robot (";
- message += std::to_string(m_specs.id());
- message += ')';
+ std::string message = " for robot (" + std::to_string(m_specs.id()) + ")";
if (m_move.has_x())
{
@@ -309,10 +296,7 @@ void SimRobot::begin(SimBall *ball, double time)
}
if (sendError)
{
- SSLSimError error{new sslsim::SimulatorError};
- error->set_code("VELOCITY_FORCE");
- error->set_message("Velocities != 0 and by_force are incompatible");
- emit sendSSLSimError(error, ErrorSource::CONFIG);
+ std::cerr << "Velocities != 0 and by_force are incompatible" << std::endl;
return;
}
} // TODO: check for force and orientation
@@ -425,23 +409,23 @@ void SimRobot::begin(SimBall *ball, double time)
// we subtract the current speed of the ball from the intended kick speed
// this ensures the ball leaves the robot at exactly the speed we want
float kickSpeed = 0.0f;
- if (ball->speed().length() < kickSpeedBoundThreshold)
+ if (ball.speed().length() < kickSpeedBoundThreshold)
{
- kickSpeed = m_sslCommand.kick_speed() -
- (ball->speed().length() / SIMULATOR_SCALE);
+ kickSpeed =
+ m_sslCommand.kick_speed() - (ball.speed().length() / SIMULATOR_SCALE);
}
else
{
kickSpeed = m_sslCommand.kick_speed();
}
- power = qBound(0.05f, kickSpeed, m_specs.shot_linear_max());
+ power = std::clamp(kickSpeed, 0.05f, m_specs.shot_linear_max());
}
else
{
// FIXME: for now we just recalc the max distance based on the given angle
const float maxShootSpeed =
coordinates::chipVelFromChipDistance(m_specs.shot_chip_max());
- power = qBound(0.05f, m_sslCommand.kick_speed(), maxShootSpeed);
+ power = std::clamp(m_sslCommand.kick_speed(), 0.05f, maxShootSpeed);
}
const auto getSpeedCompensation = [&]() -> float {
@@ -453,15 +437,16 @@ void SimRobot::begin(SimBall *ball, double time)
{
// if the ball hits the robot the chip distance actually decreases
const btVector3 relBallSpeed = relativeBallSpeed(ball) / SIMULATOR_SCALE;
- return std::max((btScalar)0, relBallSpeed.y()) -
- qBound((btScalar)0, (btScalar)0.5 * relBallSpeed.y(),
- (btScalar)0.5 * dirFloor);
+ return std::max(static_cast(0), relBallSpeed.y()) -
+ std::clamp(static_cast(0.5) * relBallSpeed.y(),
+ static_cast(0),
+ static_cast(0.5) * dirFloor);
}
};
const float speedCompensation = getSpeedCompensation();
- ball->kick(t * btVector3(0, dirFloor * power + speedCompensation, dirUp * power) *
- (1.0f / static_cast(time)) * SIMULATOR_SCALE *
- static_cast(BALL_MASS_KG));
+ ball.kick(t * btVector3(0, dirFloor * power + speedCompensation, dirUp * power) *
+ (1.0f / static_cast(time)) * SIMULATOR_SCALE *
+ static_cast(BALL_MASS_KG));
// discharge
m_isCharged = false;
m_shootTime = 0.0;
@@ -478,7 +463,8 @@ void SimRobot::begin(SimBall *ball, double time)
float output_omega = m_sslCommand.move_command().local_velocity().angular();
btVector3 v_local(t.inverse() * m_body->getLinearVelocity());
- btVector3 v_d_local(boundSpeed(output_v_s), boundSpeed(output_v_f), 0);
+ btVector3 v_d_local(std::clamp(output_v_s, -MAX_SPEED, MAX_SPEED),
+ std::clamp(output_v_f, -MAX_SPEED, MAX_SPEED), 0);
float v_f = v_local.y() / SIMULATOR_SCALE;
float v_s = v_local.x() / SIMULATOR_SCALE;
@@ -486,15 +472,15 @@ void SimRobot::begin(SimBall *ball, double time)
const float error_v_s = v_d_local.x() - v_s;
const float error_v_f = v_d_local.y() - v_f;
- const float error_omega = boundSpeed(output_omega) - omega;
+ const float error_omega = std::clamp(output_omega, -MAX_SPEED, MAX_SPEED) - omega;
- error_sum_v_s += error_v_s;
- error_sum_v_f += error_v_f;
- error_sum_omega += error_omega;
+ m_error_sum_v_s += error_v_s;
+ m_error_sum_v_f += error_v_f;
+ m_error_sum_omega += error_omega;
- const float error_sum_limit = 20.0f;
- error_sum_v_s = qBound(-error_sum_limit, error_sum_v_s, error_sum_limit);
- error_sum_v_f = qBound(-error_sum_limit, error_sum_v_f, error_sum_limit);
+ const float m_error_sum_limit = 20.0f;
+ m_error_sum_v_s = std::clamp(m_error_sum_v_s, -m_error_sum_limit, m_error_sum_limit);
+ m_error_sum_v_f = std::clamp(m_error_sum_v_f, -m_error_sum_limit, m_error_sum_limit);
// (1-(1-linear_damping)^timestep)/timestep - compensates damping
const float V = 1.200f; // keep current speed
@@ -504,8 +490,8 @@ void SimRobot::begin(SimBall *ball, double time)
// as a certain part of the acceleration is required to compensate damping,
// the robot will run into a speed limit! bound acceleration the speed limit
// is acceleration * accelScale / V
- float a_f = V * v_f + K * error_v_f + K_I * error_sum_v_f;
- float a_s = V * v_s + K * error_v_s + K_I * error_sum_v_s;
+ float a_f = V * v_f + K * error_v_f + K_I * m_error_sum_v_f;
+ float a_s = V * v_s + K * error_v_s + K_I * m_error_sum_v_s;
const float accelScale =
2.f; // let robot accelerate / brake faster than the accelerator does
@@ -524,7 +510,7 @@ void SimRobot::begin(SimBall *ball, double time)
1.f / time * 0.5f; // correct half the error during each subtimestep
const float K_I_phi = /*0*0.2/1000; //*/ 0.f;
- const float a_phi = V_phi * omega + K_phi * error_omega + K_I_phi * error_sum_omega;
+ const float a_phi = V_phi * omega + K_phi * error_omega + K_I_phi * m_error_sum_omega;
const float a_phi_bound =
bound(a_phi, omega, accelScale * m_specs.strategy().a_speedup_phi_max(),
accelScale * m_specs.strategy().a_brake_phi_max());
@@ -546,19 +532,19 @@ float SimRobot::bound(float acceleration, float oldSpeed, float speedupLimit,
if ((std::signbit(acceleration) == std::signbit(oldSpeed)) || (oldSpeed == 0))
{
// the acceleration needs to be bounded with values for speeding up.
- return qBound(-speedupLimit, acceleration, speedupLimit);
+ return std::clamp(acceleration, -speedupLimit, speedupLimit);
}
else
{
// bound braking acceleration, in order to avoid fallover
- return qBound(-brakeLimit, acceleration, brakeLimit);
+ return std::clamp(acceleration, -brakeLimit, brakeLimit);
}
}
-btVector3 SimRobot::relativeBallSpeed(SimBall *ball) const
+btVector3 SimRobot::relativeBallSpeed(const SimBall &ball) const
{
btTransform t = m_body->getWorldTransform();
- const btVector3 ballSpeed = ball->speed();
+ const btVector3 ballSpeed = ball.speed();
const btQuaternion robotDir = t.getRotation();
const btVector3 diff = (ballSpeed).rotate(robotDir.getAxis(), -robotDir.getAngle());
@@ -566,9 +552,9 @@ btVector3 SimRobot::relativeBallSpeed(SimBall *ball) const
return diff;
}
-bool SimRobot::canKickBall(SimBall *ball) const
+bool SimRobot::canKickBall(const SimBall &ball) const
{
- const btVector3 ballPos = ball->position();
+ const btVector3 ballPos = ball.position();
// can't kick jumping ball
if (ballPos.z() > 0.05f * SIMULATOR_SCALE)
{
@@ -588,8 +574,8 @@ bool SimRobot::canKickBall(SimBall *ball) const
m_world->getDispatcher()->getManifoldByIndexInternal(i);
btCollisionObject *objectA = (btCollisionObject *)(contactManifold->getBody0());
btCollisionObject *objectB = (btCollisionObject *)(contactManifold->getBody1());
- if ((objectA == m_dribblerBody && objectB == ball->body()) ||
- (objectA == ball->body() && objectB == m_dribblerBody))
+ if ((objectA == m_dribblerBody.get() && objectB == ball.body()) ||
+ (objectA == ball.body() && objectB == m_dribblerBody.get()))
{
int numContacts = contactManifold->getNumContacts();
for (int j = 0; j < numContacts; ++j)
@@ -606,7 +592,7 @@ bool SimRobot::canKickBall(SimBall *ball) const
}
robot::RadioResponse SimRobot::setCommand(const SSLSimulationProto::RobotCommand &command,
- SimBall *ball, bool charge, float rxLoss,
+ const SimBall &ball, bool charge, float rxLoss,
float txLoss)
{
m_sslCommand = command;
@@ -639,31 +625,31 @@ robot::RadioResponse SimRobot::setCommand(const SSLSimulationProto::RobotCommand
return response;
}
-void SimRobot::update(SSLProto::SSL_DetectionRobot *robot, float stddev_p,
- float stddev_phi, qint64 time, btVector3 positionOffset)
+void SimRobot::update(SSLProto::SSL_DetectionRobot &robot, float stddev_p,
+ float stddev_phi, int64_t time, btVector3 positionOffset)
{
// setup vision packet
- robot->set_robot_id(m_specs.id());
- robot->set_confidence(1.0);
- robot->set_pixel_x(0);
- robot->set_pixel_y(0);
+ robot.set_robot_id(m_specs.id());
+ robot.set_confidence(1.0);
+ robot.set_pixel_x(0);
+ robot.set_pixel_y(0);
// add noise
btTransform transform;
m_motionState->getWorldTransform(transform);
const btVector3 p = transform.getOrigin() / SIMULATOR_SCALE + positionOffset;
- const ErForceVector p_noise = m_rng->normalVector(stddev_p);
- robot->set_x((p.y() + p_noise.x) * 1000.0f);
- robot->set_y(-(p.x() + p_noise.y) * 1000.0f);
+ const ErForceVector p_noise = m_rng.normalVector(stddev_p);
+ robot.set_x((p.y() + p_noise.x) * 1000.0f);
+ robot.set_y(-(p.x() + p_noise.y) * 1000.0f);
const btQuaternion q = transform.getRotation();
const btVector3 dir = btMatrix3x3(q).getColumn(0);
- robot->set_orientation(atan2(dir.y(), dir.x()) + m_rng->normal(stddev_phi));
+ robot.set_orientation(atan2(dir.y(), dir.x()) + m_rng.normal(stddev_phi));
m_lastSendTime = time;
}
-bool SimRobot::touchesBall(SimBall *ball) const
+bool SimRobot::touchesBall(const SimBall &ball) const
{
// for some reason btHingeConstraints, which is used when dribbling, are not always
// detected as contact by bullet. so if the ball is being dribbled then we assume it
@@ -684,10 +670,10 @@ bool SimRobot::touchesBall(SimBall *ball) const
// determine if the two objects are the ball and robot body/dribbler
btCollisionObject *objectA = (btCollisionObject *)(contact_manifold->getBody0());
btCollisionObject *objectB = (btCollisionObject *)(contact_manifold->getBody1());
- if ((objectA == m_dribblerBody && objectB == ball->body()) ||
- (objectA == ball->body() && objectB == m_dribblerBody) ||
- (objectA == m_body && objectB == ball->body()) ||
- (objectA == ball->body() && objectB == m_body))
+ if ((objectA == m_dribblerBody.get() && objectB == ball.body()) ||
+ (objectA == ball.body() && objectB == m_dribblerBody.get()) ||
+ (objectA == m_body.get() && objectB == ball.body()) ||
+ (objectA == ball.body() && objectB == m_body.get()))
{
// check if the points are in contact now
int num_contacts = contact_manifold->getNumContacts();
@@ -705,18 +691,18 @@ bool SimRobot::touchesBall(SimBall *ball) const
return false;
}
-void SimRobot::update(world::SimRobot *robot, SimBall *ball) const
+void SimRobot::update(world::SimRobot &robot, const SimBall &ball) const
{
btTransform transform;
m_motionState->getWorldTransform(transform);
const btVector3 position = transform.getOrigin() / SIMULATOR_SCALE;
- robot->set_p_x(position.x());
- robot->set_p_y(position.y());
- robot->set_p_z(position.z());
- robot->set_id(m_specs.id());
+ robot.set_p_x(position.x());
+ robot.set_p_y(position.y());
+ robot.set_p_z(position.z());
+ robot.set_id(m_specs.id());
const btQuaternion q = transform.getRotation();
- auto *rotation = robot->mutable_rotation();
+ auto *rotation = robot.mutable_rotation();
rotation->set_real(q.getX());
rotation->set_i(q.getY());
rotation->set_j(q.getZ());
@@ -727,17 +713,17 @@ void SimRobot::update(world::SimRobot *robot, SimBall *ball) const
float y = 0;
float z = 0;
q.getEulerZYX(z, y, x);
- robot->set_angle(z);
+ robot.set_angle(z);
const btVector3 velocity = m_body->getLinearVelocity() / SIMULATOR_SCALE;
- robot->set_v_x(velocity.x());
- robot->set_v_y(velocity.y());
- robot->set_v_z(velocity.z());
+ robot.set_v_x(velocity.x());
+ robot.set_v_y(velocity.y());
+ robot.set_v_z(velocity.z());
const btVector3 angular = m_body->getAngularVelocity();
- robot->set_r_x(angular.x());
- robot->set_r_y(angular.y());
- robot->set_r_z(angular.z());
+ robot.set_r_x(angular.x());
+ robot.set_r_y(angular.y());
+ robot.set_r_z(angular.z());
bool ballTouchesRobot = false;
int numManifolds = m_world->getDispatcher()->getNumManifolds();
@@ -747,15 +733,15 @@ void SimRobot::update(world::SimRobot *robot, SimBall *ball) const
m_world->getDispatcher()->getManifoldByIndexInternal(i);
btCollisionObject *objectA = (btCollisionObject *)(contactManifold->getBody0());
btCollisionObject *objectB = (btCollisionObject *)(contactManifold->getBody1());
- if ((objectA == m_dribblerBody && objectB == ball->body()) ||
- (objectA == ball->body() && objectB == m_dribblerBody) ||
- (objectA == m_body && objectB == ball->body()) ||
- (objectA == ball->body() && objectB == m_body))
+ if ((objectA == m_dribblerBody.get() && objectB == ball.body()) ||
+ (objectA == ball.body() && objectB == m_dribblerBody.get()) ||
+ (objectA == m_body.get() && objectB == ball.body()) ||
+ (objectA == ball.body() && objectB == m_body.get()))
{
ballTouchesRobot = true;
}
}
- robot->set_touches_ball(ballTouchesRobot);
+ robot.set_touches_ball(ballTouchesRobot);
}
void SimRobot::restoreState(const world::SimRobot &robot)
diff --git a/src/extlibs/er_force_sim/src/amun/simulator/simrobot.h b/src/extlibs/er_force_sim/src/amun/simulator/simrobot.h
index 89c60002cb..c156f80ee5 100644
--- a/src/extlibs/er_force_sim/src/amun/simulator/simrobot.h
+++ b/src/extlibs/er_force_sim/src/amun/simulator/simrobot.h
@@ -23,62 +23,62 @@
#include
-#include
-
+#include "extlibs/er_force_sim/src/core/rng.h"
#include "extlibs/er_force_sim/src/protobuf/command.pb.h"
#include "extlibs/er_force_sim/src/protobuf/robot.pb.h"
-#include "extlibs/er_force_sim/src/protobuf/sslsim.h"
+#include "extlibs/er_force_sim/src/protobuf/world.pb.h"
#include "proto/ssl_simulation_robot_control.pb.h"
-
-class RNG;
-namespace SSLProto
-{
- class SSL_DetectionRobot;
-}
+#include "proto/ssl_vision_detection.pb.h"
+#include "simball.h"
namespace camun
{
namespace simulator
{
- class SimBall;
class SimRobot;
- enum class ErrorSource;
} // namespace simulator
} // namespace camun
-class camun::simulator::SimRobot : public QObject
+class camun::simulator::SimRobot
{
- Q_OBJECT
public:
- SimRobot(RNG *rng, const robot::Specs &specs, btDiscreteDynamicsWorld *world,
+ SimRobot(const robot::Specs &specs, std::shared_ptr world,
const btVector3 &pos, float dir);
~SimRobot();
- SimRobot(const SimRobot &) = delete;
- SimRobot &operator=(const SimRobot &) = delete;
-
- signals:
- void sendSSLSimError(const SSLSimError &error, ErrorSource s);
public:
- void begin(SimBall *ball, double time);
- bool canKickBall(SimBall *ball) const;
- void tryKick(SimBall *ball, float power, double time);
+ void begin(SimBall &ball, double time);
+
+ bool canKickBall(const SimBall &ball) const;
+
+ void tryKick(const SimBall &ball, float power, double time);
+
robot::RadioResponse setCommand(const SSLSimulationProto::RobotCommand &command,
- SimBall *ball, bool charge, float rxLoss,
+ const SimBall &ball, bool charge, float rxLoss,
float txLoss);
- void update(SSLProto::SSL_DetectionRobot *robot, float stddev_p, float stddev_phi,
- qint64 time, btVector3 positionOffset);
- void update(world::SimRobot *robot, SimBall *ball) const;
+
+ void update(SSLProto::SSL_DetectionRobot &robot, float stddev_p, float stddev_phi,
+ int64_t time, btVector3 positionOffset);
+
+ void update(world::SimRobot &robot, const SimBall &ball) const;
+
void restoreState(const world::SimRobot &robot);
+
void move(const sslsim::TeleportRobot &robot);
+
bool isFlipped();
+
btVector3 position() const;
+
btVector3 dribblerCorner(bool left) const;
- qint64 getLastSendTime() const
+
+ int64_t getLastSendTime() const
{
return m_lastSendTime;
}
+
void setDribbleMode(bool perfectDribbler);
+
void stopDribbling();
const robot::Specs &specs() const
@@ -92,34 +92,27 @@ class camun::simulator::SimRobot : public QObject
* @param ball the ball in play
* @return true if the ball is in contact with the robot, false otherwise
*/
- bool touchesBall(SimBall *ball) const;
+ bool touchesBall(const SimBall &ball) const;
private:
- btVector3 relativeBallSpeed(SimBall *ball) const;
+ btVector3 relativeBallSpeed(const SimBall &ball) const;
float bound(float acceleration, float oldSpeed, float speedupLimit,
float brakeLimit) const;
void calculateDribblerMove(const btVector3 pos, const btQuaternion rot,
const btVector3 linVel, float omega);
- void dribble(SimBall *ball, float speed);
+ void dribble(const SimBall &ball, float speed);
- RNG *m_rng;
+ RNG m_rng;
robot::Specs m_specs;
- btDiscreteDynamicsWorld *m_world;
- btRigidBody *m_body;
- btRigidBody *m_dribblerBody;
- btHingeConstraint *m_dribblerConstraint;
- QList m_shapes;
- btMotionState *m_motionState;
- btVector3 m_dribblerCenter;
+ std::shared_ptr m_world;
+ std::unique_ptr m_body;
+ std::unique_ptr m_dribblerBody;
+ std::unique_ptr m_dribblerConstraint;
+ std::vector> m_shapes;
+ std::unique_ptr m_motionState;
std::unique_ptr m_holdBallConstraint;
-
- struct Wheel
- {
- float angle;
- btVector3 pos;
- btVector3 dir;
- };
+ btVector3 m_dribblerCenter;
sslsim::TeleportRobot m_move;
SSLSimulationProto::RobotCommand m_sslCommand;
@@ -129,13 +122,13 @@ class camun::simulator::SimRobot : public QObject
double m_shootTime;
double m_commandTime;
- float error_sum_v_s;
- float error_sum_v_f;
- float error_sum_omega;
+ float m_error_sum_v_s;
+ float m_error_sum_v_f;
+ float m_error_sum_omega;
bool m_perfectDribbler = false;
- qint64 m_lastSendTime = 0;
+ int64_t m_lastSendTime = 0;
};
#endif // SIMROBOT_H
diff --git a/src/extlibs/er_force_sim/src/amun/simulator/simulator.cpp b/src/extlibs/er_force_sim/src/amun/simulator/simulator.cpp
index 2058c8a3ae..a37333174e 100644
--- a/src/extlibs/er_force_sim/src/amun/simulator/simulator.cpp
+++ b/src/extlibs/er_force_sim/src/amun/simulator/simulator.cpp
@@ -20,135 +20,52 @@
#include "simulator.h"
-#include
-#include
-#include
-#include
#include
#include
-#include "erroraggregator.h"
#include "extlibs/er_force_sim/src/core/coordinates.h"
-#include "extlibs/er_force_sim/src/core/rng.h"
#include "extlibs/er_force_sim/src/protobuf/geometry.h"
-#include "simball.h"
-#include "simfield.h"
-#include "simrobot.h"
-
using namespace camun::simulator;
-/* Friction and restitution between robots, ball and field: (empirical
- * measurments) Ball vs. Robot: Restitution: about 0.60 Friction: trial and
- * error in simulator 0.18 (similar results as in reality)
- *
- * Ball vs. Floor:
- * Restitution: sqrt(h'/h) = sqrt(0.314) = 0.56
- * Friction: \mu_k = -a / g (while slipping) = 0.35
- *
- * Robot vs. Floor:
- * Restitution and Friction should be as low as possible
- *
- * Calculations:
- * Variables: r: restitution, f: friction
- * Indices: b: ball; f: floor; r: robot
- *
- * r_b * r_f = 0.56
- * r_b * r_r = 0.60
- * r_f * r_r = small
- * => r_b = 1; r_f = 0.56; r_r = 0.60
- *
- * f_b * f_f = 0.35
- * f_b * f_r = 0.22
- * f_f * f_r = very small
- * => f_b = 1; f_f = 0.35; f_r = 0.22
- */
-
-struct camun::simulator::SimulatorData
-{
- RNG rng;
- btDefaultCollisionConfiguration *collision;
- btCollisionDispatcher *dispatcher;
- btBroadphaseInterface *overlappingPairCache;
- btSequentialImpulseConstraintSolver *solver;
- btDiscreteDynamicsWorld *dynamicsWorld;
- world::Geometry geometry;
- QVector reportedCameraSetup;
- QVector cameraPositions;
- SimField *field;
- SimBall *ball;
- Simulator::RobotMap robotsBlue;
- Simulator::RobotMap robotsYellow;
- QMap specsBlue;
- QMap specsYellow;
- bool flip;
- float stddevBall;
- float stddevBallArea;
- float stddevRobot;
- float stddevRobotPhi;
- float ballDetectionsAtDribbler; // per robot per second
- bool enableInvisibleBall;
- float ballVisibilityThreshold;
- float cameraOverlap;
- float cameraPositionError;
- float objectPositionOffset;
- float robotCommandPacketLoss;
- float robotReplyPacketLoss;
- float missingBallDetections;
- bool dribblePerfect;
-};
-
-static void simulatorTickCallback(btDynamicsWorld *world, btScalar timeStep)
-{
- Simulator *sim = reinterpret_cast(world->getWorldUserInfo());
- sim->handleSimulatorTick(timeStep);
-}
-
-/*!
- * \class Simulator
- * \ingroup simulator
- * \brief %Simulator interface
- */
-
Simulator::Simulator(const amun::SimulatorSetup &setup)
- : m_time(0),
- m_lastSentStatusTime(0),
+ : m_data(std::make_unique()),
m_enabled(false),
m_charge(true),
+ m_time(0),
m_visionDelay(35 * 1000 * 1000),
- m_visionProcessingTime(5 * 1000 * 1000),
- m_aggregator(new ErrorAggregator(this))
+ m_visionProcessingTime(5 * 1000 * 1000)
{
- // setup bullet
- m_data = new SimulatorData;
- m_data->collision = new btDefaultCollisionConfiguration();
- m_data->dispatcher = new btCollisionDispatcher(m_data->collision);
- m_data->overlappingPairCache = new btDbvtBroadphase();
- m_data->solver = new btSequentialImpulseConstraintSolver;
- m_data->dynamicsWorld =
- new btDiscreteDynamicsWorld(m_data->dispatcher, m_data->overlappingPairCache,
- m_data->solver, m_data->collision);
+ m_data->collision = std::make_unique();
+ m_data->dispatcher = std::make_unique(m_data->collision.get());
+ m_data->overlappingPairCache = std::make_unique();
+ m_data->solver = std::make_unique();
+ m_data->dynamicsWorld = std::make_shared(
+ m_data->dispatcher.get(), m_data->overlappingPairCache.get(),
+ m_data->solver.get(), m_data->collision.get());
m_data->dynamicsWorld->setGravity(btVector3(0.0f, 0.0f, -9.81f * SIMULATOR_SCALE));
- m_data->dynamicsWorld->setInternalTickCallback(simulatorTickCallback, this, true);
+ m_data->dynamicsWorld->setInternalTickCallback(
+ [](btDynamicsWorld *world, btScalar timeStep) {
+ Simulator *sim = reinterpret_cast(world->getWorldUserInfo());
+ sim->handleSimulatorTick(timeStep);
+ },
+ this, true);
m_data->geometry.CopyFrom(setup.geometry());
for (const auto &camera : setup.camera_setup())
{
- m_data->reportedCameraSetup.append(camera);
+ m_data->reportedCameraSetup.push_back(camera);
ErForceVector visionPosition(camera.derived_camera_world_tx(),
camera.derived_camera_world_ty());
btVector3 truePosition;
coordinates::fromVision(visionPosition, truePosition);
truePosition.setZ(camera.derived_camera_world_tz() / 1000.0f);
- m_data->cameraPositions.append(truePosition);
+ m_data->cameraPositions.push_back(truePosition);
}
- // add field and ball
- m_data->field = new SimField(m_data->dynamicsWorld, m_data->geometry);
- m_data->ball = new SimBall(&m_data->rng, m_data->dynamicsWorld);
- connect(m_data->ball, &SimBall::sendSSLSimError, m_aggregator,
- &ErrorAggregator::aggregate);
- m_data->flip = false;
+ m_data->field = std::make_unique(m_data->dynamicsWorld, m_data->geometry);
+ m_data->ball = std::make_shared(m_data->dynamicsWorld);
+ m_data->flip = false;
m_data->stddevBall = 0.0f;
m_data->stddevBallArea = 0.0f;
m_data->stddevRobot = 0.0f;
@@ -167,32 +84,6 @@ Simulator::Simulator(const amun::SimulatorSetup &setup)
// no robots after initialisation
}
-// does delete all Simrobots in the RobotMap, does not clear map
-// (just like qDeleteAll would)
-static void deleteAll(const Simulator::RobotMap &map)
-{
- for (const auto &e : map)
- {
- delete e.first;
- }
-}
-
-Simulator::~Simulator()
-{
- resetVisionPackets();
-
- deleteAll(m_data->robotsBlue);
- deleteAll(m_data->robotsYellow);
- delete m_data->ball;
- delete m_data->field;
- delete m_data->dynamicsWorld;
- delete m_data->solver;
- delete m_data->overlappingPairCache;
- delete m_data->dispatcher;
- delete m_data->collision;
- delete m_data;
-}
-
std::vector Simulator::acceptBlueRobotControlCommand(
const SSLSimulationProto::RobotControl &control)
{
@@ -211,65 +102,35 @@ std::vector Simulator::acceptRobotControlCommand(
// collect responses from robots
std::vector responses;
+ Simulator::RobotMap &robotMap = isBlue ? m_data->robotsBlue : m_data->robotsYellow;
+
for (const SSLSimulationProto::RobotCommand &command : control.robot_commands())
{
- // pass radio command to robot that matches the id
- const auto id = command.id();
- SimulatorData *data = m_data;
- auto time = m_time;
- auto charge = m_charge;
- auto fabricateResponse = [data, &responses, time, charge, &id, &command](
- const Simulator::RobotMap &map, const bool *isBlue) {
- if (!map.contains(id))
- return;
- robot::RadioResponse response = map[id].first->setCommand(
- command, data->ball, charge, data->robotCommandPacketLoss,
- data->robotReplyPacketLoss);
- response.set_time(time);
-
- if (isBlue != nullptr)
- {
- response.set_is_blue(*isBlue);
- }
- // only collect valid responses
- if (response.IsInitialized())
- {
- if (data->robotReplyPacketLoss == 0 ||
- data->rng.uniformFloat(0, 1) > data->robotReplyPacketLoss)
- {
- responses.emplace_back(response);
- }
- }
- };
- if (isBlue)
+ if (!robotMap.contains(command.id()))
{
- fabricateResponse(m_data->robotsBlue, &isBlue);
+ return responses;
}
- else
+
+ // pass radio command to robot that matches the id
+ robot::RadioResponse response = robotMap.at(command.id())
+ ->setCommand(command, *m_data->ball, m_charge,
+ m_data->robotCommandPacketLoss,
+ m_data->robotReplyPacketLoss);
+ response.set_time(m_time);
+ response.set_is_blue(isBlue);
+
+ // only collect valid responses
+ if (response.IsInitialized())
{
- fabricateResponse(m_data->robotsYellow, &isBlue);
+ if (m_data->robotReplyPacketLoss == 0 ||
+ m_data->rng.uniformFloat(0, 1) > m_data->robotReplyPacketLoss)
+ {
+ responses.emplace_back(response);
+ }
}
}
- return responses;
-}
-void Simulator::sendSSLSimErrorInternal(ErrorSource source)
-{
- QList errors = m_aggregator->getAggregates(source);
- if (errors.size() == 0)
- return;
- emit sendSSLSimError(errors, source);
-}
-
-static void createRobot(Simulator::RobotMap &list, float x, float y, uint32_t id,
- const ErrorAggregator *agg, SimulatorData *data,
- const QMap &teamSpecs)
-{
- SimRobot *robot = new SimRobot(&data->rng, teamSpecs[id], data->dynamicsWorld,
- btVector3(x, y, 0), 0.f);
- robot->setDribbleMode(data->dribblePerfect);
- robot->connect(robot, &SimRobot::sendSSLSimError, agg, &ErrorAggregator::aggregate);
- list[id] = {robot, teamSpecs[id].generation()};
+ return responses;
}
void Simulator::resetFlipped(Simulator::RobotMap &robots, float side)
@@ -278,22 +139,13 @@ void Simulator::resetFlipped(Simulator::RobotMap &robots, float side)
const float x = m_data->geometry.field_width() / 2 - 0.2;
float y = m_data->geometry.field_height() / 2 - 0.2;
- for (RobotMap::iterator it = robots.begin(); it != robots.end(); ++it)
+ for (auto &[robotId, robot] : robots)
{
- SimRobot *robot = it.value().first;
if (robot->isFlipped())
{
- SimRobot *new_robot =
- new SimRobot(&m_data->rng, robot->specs(), m_data->dynamicsWorld,
- btVector3(x, side * y, 0), 0.0f);
- delete robot;
- connect(new_robot, &SimRobot::sendSSLSimError, m_aggregator,
- &ErrorAggregator::aggregate); // TODO? use createRobot instead of
- // this. However, doing so naively
- // will break the iteration, so I
- // left it for now.
- new_robot->setDribbleMode(m_data->dribblePerfect);
- it.value().first = new_robot;
+ robot = std::make_unique(robot->specs(), m_data->dynamicsWorld,
+ btVector3(x, side * y, 0), 0.0f);
+ robot->setDribbleMode(m_data->dribblePerfect);
}
y -= 0.3;
}
@@ -314,17 +166,14 @@ void Simulator::handleSimulatorTick(double time_s)
resetFlipped(m_data->robotsYellow, -1.0f);
if (m_data->ball->isInvalid())
{
- delete m_data->ball;
- m_data->ball = new SimBall(&m_data->rng, m_data->dynamicsWorld);
- connect(m_data->ball, &SimBall::sendSSLSimError, m_aggregator,
- &ErrorAggregator::aggregate);
+ m_data->ball = std::make_shared(m_data->dynamicsWorld);
}
// find out if ball and any robot collide
- auto robot_ball_collision = [this](QPair elem) {
- return elem.first->touchesBall(this->m_data->ball);
+ auto robot_ball_collision = [&](const auto &kv_pair) {
+ auto &[robotId, robot] = kv_pair;
+ return robot->touchesBall(*m_data->ball);
};
-
bool ball_collision = std::any_of(m_data->robotsBlue.begin(),
m_data->robotsBlue.end(), robot_ball_collision) ||
std::any_of(m_data->robotsYellow.begin(),
@@ -332,13 +181,13 @@ void Simulator::handleSimulatorTick(double time_s)
// apply commands and forces to ball and robots
m_data->ball->begin(ball_collision);
- for (const auto &pair : m_data->robotsBlue)
+ for (auto &[robotId, robot] : m_data->robotsBlue)
{
- pair.first->begin(m_data->ball, time_s);
+ robot->begin(*m_data->ball, time_s);
}
- for (const auto &pair : m_data->robotsYellow)
+ for (auto &[robotId, robot] : m_data->robotsYellow)
{
- pair.first->begin(m_data->ball, time_s);
+ robot->begin(*m_data->ball, time_s);
}
// add gravity to all ACTIVE objects
@@ -347,7 +196,8 @@ void Simulator::handleSimulatorTick(double time_s)
}
static bool checkCameraID(const int cameraId, const btVector3 &p,
- const QVector &cameraPositions, const float overlap)
+ const std::vector &cameraPositions,
+ const float overlap)
{
float minDistance = std::numeric_limits::max();
float ownDistance = 0;
@@ -366,13 +216,13 @@ static bool checkCameraID(const int cameraId, const btVector3 &p,
return ownDistance <= minDistance + 2 * overlap;
}
-void Simulator::initializeDetection(SSLProto::SSL_DetectionFrame *detection,
- std::size_t cameraId)
+void Simulator::initializeDetection(SSLProto::SSL_DetectionFrame &detection,
+ size_t cameraId)
{
- detection->set_frame_number(m_lastFrameNumber[cameraId]++);
- detection->set_camera_id(cameraId);
- detection->set_t_capture((m_time + m_visionDelay - m_visionProcessingTime) * 1E-9);
- detection->set_t_sent((m_time + m_visionDelay) * 1E-9);
+ detection.set_frame_number(m_lastFrameNumber[cameraId]++);
+ detection.set_camera_id(cameraId);
+ detection.set_t_capture((m_time + m_visionDelay - m_visionProcessingTime) * 1E-9);
+ detection.set_t_sent((m_time + m_visionDelay) * 1E-9);
}
static btVector3 positionOffsetForCamera(float offsetStrength, btVector3 cameraPos)
@@ -398,7 +248,7 @@ std::vector Simulator::getWrapperPackets()
std::vector detections(numCameras);
for (std::size_t i = 0; i < numCameras; i++)
{
- initializeDetection(&detections[i], i);
+ initializeDetection(detections[i], i);
}
bool missingBall = m_data->missingBallDetections > 0 &&
@@ -421,7 +271,7 @@ std::vector Simulator::getWrapperPackets()
const btVector3 positionOffset = positionOffsetForCamera(
m_data->objectPositionOffset, m_data->cameraPositions[cameraId]);
bool visible = m_data->ball->update(
- detections[cameraId].add_balls(), m_data->stddevBall,
+ *detections[cameraId].add_balls(), m_data->stddevBall,
m_data->stddevBallArea, m_data->cameraPositions[cameraId],
m_data->enableInvisibleBall, m_data->ballVisibilityThreshold,
positionOffset);
@@ -433,14 +283,12 @@ std::vector Simulator::getWrapperPackets()
}
// get robot positions
- for (bool teamIsBlue : {true, false})
+ for (auto &[teamIsBlue, team] :
+ {std::make_tuple(true, std::ref(m_data->robotsBlue)),
+ std::make_tuple(false, std::ref(m_data->robotsYellow))})
{
- auto &team = teamIsBlue ? m_data->robotsBlue : m_data->robotsYellow;
-
- for (const auto &it : team)
+ for (auto &[robotId, robot] : team)
{
- SimRobot *robot = it.first;
-
if (m_time - robot->getLastSendTime() >= m_minRobotDetectionTime)
{
const float timeDiff = (m_time - robot->getLastSendTime()) * 1E-9;
@@ -458,13 +306,13 @@ std::vector Simulator::getWrapperPackets()
m_data->objectPositionOffset, m_data->cameraPositions[cameraId]);
if (teamIsBlue)
{
- robot->update(detections[cameraId].add_robots_blue(),
+ robot->update(*detections[cameraId].add_robots_blue(),
m_data->stddevRobot, m_data->stddevRobotPhi, m_time,
positionOffset);
}
else
{
- robot->update(detections[cameraId].add_robots_yellow(),
+ robot->update(*detections[cameraId].add_robots_yellow(),
m_data->stddevRobot, m_data->stddevRobotPhi, m_time,
positionOffset);
}
@@ -478,7 +326,7 @@ std::vector Simulator::getWrapperPackets()
{
// always on the right side of the dribbler for now
if (!m_data->ball->addDetection(
- detections[cameraId].add_balls(),
+ *detections[cameraId].add_balls(),
robot->dribblerCorner(false) / SIMULATOR_SCALE,
m_data->stddevRobot, 0, m_data->cameraPositions[cameraId],
false, 0, positionOffset))
@@ -555,70 +403,46 @@ world::SimulatorState Simulator::getSimulatorState()
const std::size_t numCameras = m_data->reportedCameraSetup.size();
world::SimulatorState simState;
- auto *ball = simState.mutable_ball();
- m_data->ball->writeBallState(ball);
+ m_data->ball->writeBallState(*simState.mutable_ball());
// get robot positions
for (bool teamIsBlue : {true, false})
{
auto &team = teamIsBlue ? m_data->robotsBlue : m_data->robotsYellow;
- for (const auto &it : team)
+ for (auto &[robotId, robot] : team)
{
- SimRobot *robot = it.first;
-
// convert coordinates from ER Force
btVector3 robotPos = robot->position() / SIMULATOR_SCALE;
btVector3 newRobotPos;
coordinates::toVision(robotPos, newRobotPos);
- auto *robotProto =
- teamIsBlue ? simState.add_blue_robots() : simState.add_yellow_robots();
+ auto &robotProto =
+ teamIsBlue ? *simState.add_blue_robots() : *simState.add_yellow_robots();
- robot->update(robotProto, m_data->ball);
+ robot->update(robotProto, *m_data->ball);
// Convert mm to m
- robotProto->set_p_x(newRobotPos.x() / 1000);
- robotProto->set_p_y(newRobotPos.y() / 1000);
+ robotProto.set_p_x(newRobotPos.x() / 1000);
+ robotProto.set_p_y(newRobotPos.y() / 1000);
// Convert velocity
- coordinates::toVisionVelocity(*robotProto, *robotProto);
- robotProto->set_v_x(robotProto->v_x() / 1000);
- robotProto->set_v_y(robotProto->v_y() / 1000);
+ coordinates::toVisionVelocity(robotProto, robotProto);
+ robotProto.set_v_x(robotProto.v_x() / 1000);
+ robotProto.set_v_y(robotProto.v_y() / 1000);
}
}
return simState;
}
-void Simulator::resetVisionPackets()
-{
- qDeleteAll(m_visionTimers);
- m_visionTimers.clear();
- m_visionPackets.clear();
-}
-
-void Simulator::handleRadioCommands(const SSLSimRobotControl &commands, bool isBlue,
- qint64 processingStart)
-{
- m_radioCommands.enqueue(std::make_tuple(commands, processingStart, isBlue));
-}
-
-void Simulator::setTeam(Simulator::RobotMap &list, float side, const robot::Team &team,
- QMap &teamSpecs)
+void Simulator::setTeam(Simulator::RobotMap &robotMap, float side,
+ const robot::Team &team,
+ std::map &teamSpecs)
{
// remove old team
- deleteAll(list);
- list.clear();
-
- // changing a team is also triggering a tracking reset
- // thus the old robots will disappear immediatelly
- // however if the delayed vision packets arrive the old robots will be tracked
- // again thus after removing a robot from a team it can take 1 simulated
- // second for the robot to disappear to prevent this remove outdated vision
- // packets
- resetVisionPackets();
+ robotMap.clear();
// align robots on a line
const float x = m_data->geometry.field_width() / 2 - 0.2;
@@ -630,14 +454,17 @@ void Simulator::setTeam(Simulator::RobotMap &list, float side, const robot::Team
const auto id = specs.id();
// (color, robot id) must be unique
- if (list.contains(id))
+ if (robotMap.contains(id))
{
std::cerr << "Error: Two ids for the same color, aborting!" << std::endl;
continue;
}
teamSpecs[id].CopyFrom(specs);
- createRobot(list, x, side * y, id, m_aggregator, m_data, teamSpecs);
+ robotMap[id] = std::make_unique(teamSpecs[id], m_data->dynamicsWorld,
+ btVector3(x, side * y, 0), 0.f);
+ robotMap[id]->setDribbleMode(m_data->dribblePerfect);
+
y -= 0.3;
}
}
@@ -656,12 +483,13 @@ void Simulator::moveBall(const sslsim::TeleportBall &ball)
// remove the dribbling constraint
if (!ball.has_by_force() || !ball.by_force())
{
- for (const auto &robotList : {m_data->robotsBlue, m_data->robotsYellow})
+ for (auto &[robotId, robot] : m_data->robotsBlue)
{
- for (const auto &it : robotList)
- {
- it.first->stopDribbling();
- }
+ robot->stopDribbling();
+ }
+ for (auto &[robotId, robot] : m_data->robotsYellow)
+ {
+ robot->stopDribbling();
}
}
@@ -690,12 +518,11 @@ void Simulator::moveRobot(const sslsim::TeleportRobot &robot)
if (!robot.id().has_id())
return;
- bool is_blue = robot.id().team() == gameController::Team::BLUE;
-
- RobotMap &list = is_blue ? m_data->robotsBlue : m_data->robotsYellow;
- bool isPresent = list.contains(robot.id().id());
- QMap &teamSpecs =
- is_blue ? m_data->specsBlue : m_data->specsYellow;
+ bool isBlue = robot.id().team() == gameController::Team::BLUE;
+ RobotMap &robotMap = isBlue ? m_data->robotsBlue : m_data->robotsYellow;
+ bool isPresent = robotMap.contains(robot.id().id());
+ std::map &teamSpecs =
+ isBlue ? m_data->specsBlue : m_data->specsYellow;
if (robot.has_present())
{
@@ -704,39 +531,31 @@ void Simulator::moveRobot(const sslsim::TeleportRobot &robot)
// add the requested robot
if (!teamSpecs.contains(robot.id().id()))
{
- SSLSimError error{new sslsim::SimulatorError};
- error->set_code("CREATE_UNSPEC_ROBOT");
- std::string message =
- "trying to create robot " + std::to_string(robot.id().id());
- message += ", but no spec for this robot was found";
- error->set_message(std::move(message));
- m_aggregator->aggregate(error, ErrorSource::CONFIG);
+ std::cerr << "Trying to create robot " << std::to_string(robot.id().id())
+ << ", but no spec for this robot was found" << std::endl;
}
else if (!robot.has_x() || !robot.has_y())
{
- SSLSimError error{new sslsim::SimulatorError};
- error->set_code("CREATE_NOPOS_ROBOT");
- std::string message =
- "trying to create robot " + std::to_string(robot.id().id());
- message += " without giving a position";
- error->set_message(std::move(message));
- m_aggregator->aggregate(error, ErrorSource::CONFIG);
+ std::cerr << "Trying to create robot " << std::to_string(robot.id().id())
+ << ", without giving a position" << std::endl;
}
else
{
ErForceVector targetPos;
coordinates::fromVision(robot, targetPos);
// TODO: check if the given position is fine
- createRobot(list, targetPos.x, targetPos.y, robot.id().id(), m_aggregator,
- m_data, teamSpecs);
+
+ robotMap[robot.id().id()] = std::make_unique(
+ teamSpecs[robot.id().id()], m_data->dynamicsWorld,
+ btVector3(targetPos.x, targetPos.y, 0), 0.f);
+ robotMap[robot.id().id()]->setDribbleMode(m_data->dribblePerfect);
}
}
else if (!robot.present() && isPresent)
{
// remove the robot
- auto val = list.take(robot.id().id());
- val.first->stopDribbling();
- delete val.first;
+ robotMap.at(robot.id().id())->stopDribbling();
+ robotMap.erase(robot.id().id());
return;
}
else if (!robot.present() && !isPresent)
@@ -752,8 +571,8 @@ void Simulator::moveRobot(const sslsim::TeleportRobot &robot)
return;
}
- if (!list.contains(robot.id().id()))
- return; // Recheck the list in case the has_present paragraph did change it.
+ if (!robotMap.contains(robot.id().id()))
+ return; // Recheck the robotMap in case the has_present paragraph did change it.
sslsim::TeleportRobot r = robot;
@@ -765,17 +584,11 @@ void Simulator::moveRobot(const sslsim::TeleportRobot &robot)
FLIP(r, v_y);
}
- SimRobot *sim_robot = list[robot.id().id()].first;
if (!r.has_by_force() || !r.by_force())
{
- sim_robot->stopDribbling();
+ robotMap[robot.id().id()]->stopDribbling();
}
- sim_robot->move(r);
-}
-
-void Simulator::setFlipped(bool flipped)
-{
- m_data->flip = flipped;
+ robotMap[robot.id().id()]->move(r);
}
void Simulator::handleSimulatorSetupCommand(const std::unique_ptr &command)
@@ -785,6 +598,7 @@ void Simulator::handleSimulatorSetupCommand(const std::unique_ptr
if (command->has_simulator())
{
const amun::CommandSimulator &sim = command->simulator();
+
if (sim.has_enable())
{
m_enabled = sim.enable();
@@ -793,6 +607,7 @@ void Simulator::handleSimulatorSetupCommand(const std::unique_ptr
if (sim.has_realism_config())
{
auto realism = sim.realism_config();
+
if (realism.has_stddev_ball_p())
{
m_data->stddevBall = realism.stddev_ball_p();
@@ -860,13 +675,12 @@ void Simulator::handleSimulatorSetupCommand(const std::unique_ptr
if (realism.has_vision_delay())
{
- m_visionDelay = std::max((qint64)0, (qint64)realism.vision_delay());
+ m_visionDelay = std::max(0l, realism.vision_delay());
}
if (realism.has_vision_processing_time())
{
- m_visionProcessingTime =
- std::max((qint64)0, (qint64)realism.vision_processing_time());
+ m_visionProcessingTime = std::max(0l, realism.vision_processing_time());
}
if (realism.has_simulate_dribbling())
@@ -914,7 +728,7 @@ void Simulator::handleSimulatorSetupCommand(const std::unique_ptr
{
if (map.contains(robot.id()))
{
- map[robot.id()].first->restoreState(robot);
+ map[robot.id()]->restoreState(robot);
}
}
};
@@ -926,10 +740,9 @@ void Simulator::handleSimulatorSetupCommand(const std::unique_ptr
if (command->has_transceiver())
{
- const amun::CommandTransceiver &t = command->transceiver();
- if (t.has_charge())
+ if (command->transceiver().has_charge())
{
- m_charge = t.charge();
+ m_charge = command->transceiver().charge();
}
}
@@ -948,73 +761,13 @@ void Simulator::handleSimulatorSetupCommand(const std::unique_ptr
if (teamOrPerfectDribbleChanged)
{
- for (const auto &robotList : {m_data->robotsBlue, m_data->robotsYellow})
+ for (auto &[robotId, robot] : m_data->robotsBlue)
{
- for (const auto &it : robotList)
- {
- SimRobot *robot = it.first;
- robot->setDribbleMode(m_data->dribblePerfect);
- }
+ robot->setDribbleMode(m_data->dribblePerfect);
}
- }
-}
-
-void Simulator::seedPRGN(uint32_t seed)
-{
- m_data->rng.seed(seed);
-}
-
-static bool overlapCheck(const btVector3 &p0, const float &r0, const btVector3 &p1,
- const float &r1)
-{
- const float distance = (p1 - p0).length();
- return distance <= r0 + r1;
-}
-
-// uses the real world scale
-void Simulator::teleportRobotToFreePosition(SimRobot *robot)
-{
- btVector3 robotPos = robot->position() / SIMULATOR_SCALE;
- btVector3 direction =
- (robotPos - m_data->ball->position() / SIMULATOR_SCALE).normalize();
- float distance =
- 2.0f * (static_cast(BALL_MAX_RADIUS_METERS) + robot->specs().radius());
- bool valid = true;
- do
- {
- valid = true;
- robotPos = robotPos + 2 * direction * distance;
-
- for (const auto &robotList : {m_data->robotsBlue, m_data->robotsYellow})
+ for (auto &[robotId, robot] : m_data->robotsYellow)
{
- for (const auto &it : robotList)
- {
- SimRobot *robot2 = it.first;
- if (robot == robot2)
- {
- continue;
- }
-
- btVector3 tmp = robot2->position() / SIMULATOR_SCALE;
- if (overlapCheck(robotPos, robot->specs().radius(), tmp,
- robot2->specs().radius()))
- {
- valid = false;
- break;
- }
- }
- if (!valid)
- {
- break;
- }
+ robot->setDribbleMode(m_data->dribblePerfect);
}
- } while (!valid);
-
- sslsim::TeleportRobot robotCommand;
- robotCommand.mutable_id()->set_id(robot->specs().id());
- coordinates::toVision(robotPos, robotCommand);
-
- robotCommand.set_v_x(0);
- robotCommand.set_v_y(0);
- robot->move(robotCommand);
+ }
}
diff --git a/src/extlibs/er_force_sim/src/amun/simulator/simulator.h b/src/extlibs/er_force_sim/src/amun/simulator/simulator.h
index f9cbb77432..48d3560c15 100644
--- a/src/extlibs/er_force_sim/src/amun/simulator/simulator.h
+++ b/src/extlibs/er_force_sim/src/amun/simulator/simulator.h
@@ -21,19 +21,16 @@
#ifndef SIMULATOR_H
#define SIMULATOR_H
-#include
-#include
-#include
-#include
-#include
+#include
#include
-#include
+#include
-#include "extlibs/er_force_sim/src/protobuf/command.h"
-#include "extlibs/er_force_sim/src/protobuf/sslsim.h"
+#include "extlibs/er_force_sim/src/core/rng.h"
#include "proto/ssl_simulation_robot_control.pb.h"
#include "proto/ssl_vision_wrapper.pb.h"
-
+#include "simball.h"
+#include "simfield.h"
+#include "simrobot.h"
// higher values break the rolling friction of the ball
const float SIMULATOR_SCALE = 10.0f;
@@ -41,37 +38,19 @@ const float SUB_TIMESTEP = 1 / 200.f;
const float COLLISION_MARGIN = 0.04f;
const float FOCAL_LENGTH = 390.f;
-
-class QByteArray;
-class QTimer;
-class Timer;
-class SSL_GeometryFieldSize;
-
namespace camun
{
namespace simulator
{
- class SimRobot;
class Simulator;
- class ErrorAggregator;
struct SimulatorData;
-
- enum class ErrorSource
- {
- BLUE,
- YELLOW,
- CONFIG
- };
} // namespace simulator
} // namespace camun
-class camun::simulator::Simulator : public QObject
+class camun::simulator::Simulator
{
- Q_OBJECT
-
public:
- typedef QMap>
- RobotMap; /*First int: ID, Second int: Generation*/
+ typedef std::map> RobotMap;
/**
* Creates a simulator with the given set up
@@ -79,22 +58,6 @@ class camun::simulator::Simulator : public QObject
* @param setup the simulator set up
*/
explicit Simulator(const amun::SimulatorSetup &setup);
- ~Simulator() override;
- Simulator(const Simulator &) = delete;
- Simulator &operator=(const Simulator &) = delete;
-
- /**
- * Seeds the pseudorandom generator
- *
- * @param seed
- */
- void seedPRGN(uint32_t seed);
-
- signals:
- void gotPacket(const QByteArray &data, qint64 time, QString sender);
- void sendRadioResponses(const QList &responses);
- void sendRealData(const QByteArray &data); // sends amun::SimulatorState
- void sendSSLSimError(const QList &errors, ErrorSource source);
public:
/**
@@ -145,11 +108,6 @@ class camun::simulator::Simulator : public QObject
*/
void handleSimulatorSetupCommand(const std::unique_ptr &command);
- public slots:
- void handleRadioCommands(const SSLSimRobotControl &control, bool isBlue,
- qint64 processingStart);
- void setFlipped(bool flipped);
-
private:
/**
* Accepts and executes a blue or yellow robot control command
@@ -161,42 +119,91 @@ class camun::simulator::Simulator : public QObject
*/
std::vector acceptRobotControlCommand(
const SSLSimulationProto::RobotControl &control, bool isBlue);
- void sendSSLSimErrorInternal(ErrorSource source);
+
void resetFlipped(RobotMap &robots, float side);
- std::tuple, QByteArray, qint64> createVisionPacket();
- void resetVisionPackets();
void setTeam(RobotMap &list, float side, const robot::Team &team,
- QMap &specs);
+ std::map &specs);
void moveBall(const sslsim::TeleportBall &ball);
void moveRobot(const sslsim::TeleportRobot &robot);
- void teleportRobotToFreePosition(SimRobot *robot);
- void initializeDetection(SSLProto::SSL_DetectionFrame *detection,
- std::size_t cameraId);
+ void initializeDetection(SSLProto::SSL_DetectionFrame &detection, size_t cameraId);
private:
- typedef std::tuple RadioCommand;
- SimulatorData *m_data;
- QQueue m_radioCommands;
- QQueue, QByteArray, qint64>> m_visionPackets;
- QQueue m_visionTimers;
- QTimer *m_trigger;
- qint64 m_time;
- qint64 m_lastSentStatusTime;
+ std::unique_ptr m_data;
+
bool m_enabled;
bool m_charge;
- // systemDelay + visionProcessingTime = visionDelay
- qint64 m_visionDelay;
- qint64 m_visionProcessingTime;
-
- qint64 m_minRobotDetectionTime = 0;
- qint64 m_minBallDetectionTime = 0;
- qint64 m_lastBallSendTime = 0;
- std::map m_lastFrameNumber;
- ErrorAggregator *m_aggregator;
+ int64_t m_time;
+ int64_t m_visionDelay; // systemDelay + visionProcessingTime = visionDelay
+ int64_t m_visionProcessingTime;
+ int64_t m_minRobotDetectionTime = 0;
+ int64_t m_minBallDetectionTime = 0;
+ int64_t m_lastBallSendTime = 0;
+ std::map m_lastFrameNumber;
std::mt19937 rand_shuffle_src = std::mt19937(std::random_device()());
};
+
+/* Friction and restitution between robots, ball and field: (empirical
+ * measurments) Ball vs. Robot: Restitution: about 0.60 Friction: trial and
+ * error in simulator 0.18 (similar results as in reality)
+ *
+ * Ball vs. Floor:
+ * Restitution: sqrt(h'/h) = sqrt(0.314) = 0.56
+ * Friction: \mu_k = -a / g (while slipping) = 0.35
+ *
+ * Robot vs. Floor:
+ * Restitution and Friction should be as low as possible
+ *
+ * Calculations:
+ * Variables: r: restitution, f: friction
+ * Indices: b: ball; f: floor; r: robot
+ *
+ * r_b * r_f = 0.56
+ * r_b * r_r = 0.60
+ * r_f * r_r = small
+ * => r_b = 1; r_f = 0.56; r_r = 0.60
+ *
+ * f_b * f_f = 0.35
+ * f_b * f_r = 0.22
+ * f_f * f_r = very small
+ * => f_b = 1; f_f = 0.35; f_r = 0.22
+ */
+
+struct camun::simulator::SimulatorData
+{
+ RNG rng;
+ std::unique_ptr collision;
+ std::unique_ptr dispatcher;
+ std::unique_ptr overlappingPairCache;
+ std::unique_ptr solver;
+ std::shared_ptr dynamicsWorld;
+ world::Geometry geometry;
+ std::vector reportedCameraSetup;
+ std::vector cameraPositions;
+ std::unique_ptr field;
+ std::shared_ptr ball;
+ Simulator::RobotMap robotsBlue;
+ Simulator::RobotMap robotsYellow;
+ std::map specsBlue;
+ std::map specsYellow;
+ bool flip;
+ float stddevBall;
+ float stddevBallArea;
+ float stddevRobot;
+ float stddevRobotPhi;
+ float ballDetectionsAtDribbler; // per robot per second
+ bool enableInvisibleBall;
+ float ballVisibilityThreshold;
+ float cameraOverlap;
+ float cameraPositionError;
+ float objectPositionOffset;
+ float robotCommandPacketLoss;
+ float robotReplyPacketLoss;
+ float missingBallDetections;
+ bool dribblePerfect;
+};
+
#endif // SIMULATOR_H
diff --git a/src/extlibs/er_force_sim/src/core/BUILD b/src/extlibs/er_force_sim/src/core/BUILD
index 517319b07a..475d773201 100644
--- a/src/extlibs/er_force_sim/src/core/BUILD
+++ b/src/extlibs/er_force_sim/src/core/BUILD
@@ -1,16 +1,9 @@
-load("@bazel_rules_qt//:qt.bzl", "qt_cc_library")
-
package(default_visibility = ["//visibility:public"])
-qt_cc_library(
- name = "core_qt",
+cc_library(
+ name = "core",
srcs = glob(
["*.cpp"],
),
hdrs = glob(["*.h"]),
- deps = [
- "@qt//:qt_core",
- "@qt//:qt_gui",
- "@qt//:qt_widgets",
- ],
)
diff --git a/src/extlibs/er_force_sim/src/core/configuration.h b/src/extlibs/er_force_sim/src/core/configuration.h
deleted file mode 100644
index 0cfb4fe8a7..0000000000
--- a/src/extlibs/er_force_sim/src/core/configuration.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
- * Copyright 2021 Andreas Wendler *
- * Robotics Erlangen e.V. *
- * http://www.robotics-erlangen.de/ *
- * info@robotics-erlangen.de *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see . *
- ***************************************************************************/
-
-#ifndef CONFIGURATION_H
-#define CONFIGURATION_H
-
-#include
-#include
-
-#include
-#include
-#include
-
-#include "src/config/config.h"
-
-inline bool loadConfiguration(const QString &configFile,
- google::protobuf::Message *message, bool allowPartial)
-{
- QString fullFilename = QString(ERFORCE_CONFDIR) + configFile + ".txt";
- QFile file(fullFilename);
- if (!file.open(QFile::ReadOnly))
- {
- std::cout << "Could not open configuration file " << fullFilename.toStdString()
- << std::endl;
- return false;
- }
- QString str = file.readAll();
- file.close();
- std::string s = qPrintable(str);
-
- google::protobuf::TextFormat::Parser parser;
- parser.AllowPartialMessage(allowPartial);
- parser.ParseFromString(s, message);
- return true;
-}
-
-#endif // CONFIGURATION_H
diff --git a/src/extlibs/er_force_sim/src/core/protobuffilereader.cpp b/src/extlibs/er_force_sim/src/core/protobuffilereader.cpp
deleted file mode 100644
index 80e9f00f62..0000000000
--- a/src/extlibs/er_force_sim/src/core/protobuffilereader.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/***************************************************************************
- * Copyright 2020 Andreas Wendler *
- * Robotics Erlangen e.V. *
- * http://www.robotics-erlangen.de/ *
- * info@robotics-erlangen.de *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see . *
- ***************************************************************************/
-
-#include "protobuffilereader.h"
-
-ProtobufFileReader::ProtobufFileReader() : m_stream(&m_file) {}
-
-bool ProtobufFileReader::open(QString filename, QString filePrefix)
-{
- m_file.setFileName(filename);
- if (!m_file.open(QIODevice::ReadOnly))
- {
- return false;
- }
-
- // ensure compatibility across qt versions
- m_stream.setVersion(QDataStream::Qt_4_6);
-
- QString fileType;
- int version;
- m_stream >> fileType >> version;
-
- if (fileType != filePrefix || version != 0)
- {
- return false;
- }
-
- return true;
-}
-
-bool ProtobufFileReader::readNext(google::protobuf::Message &message)
-{
- if (m_stream.atEnd())
- {
- return false;
- }
- QByteArray data;
- m_stream >> data;
-
- if (!message.ParseFromArray(data.data(), data.size()))
- {
- return false;
- }
- return true;
-}
diff --git a/src/extlibs/er_force_sim/src/core/protobuffilereader.h b/src/extlibs/er_force_sim/src/core/protobuffilereader.h
deleted file mode 100644
index 957c2e4a20..0000000000
--- a/src/extlibs/er_force_sim/src/core/protobuffilereader.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/***************************************************************************
- * Copyright 2020 Andreas Wendler *
- * Robotics Erlangen e.V. *
- * http://www.robotics-erlangen.de/ *
- * info@robotics-erlangen.de *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see . *
- ***************************************************************************/
-
-#ifndef PROTOBUFFILEREADER_H
-#define PROTOBUFFILEREADER_H
-
-#include
-
-#include
-#include
-
-class ProtobufFileReader : public QObject
-{
- public:
- ProtobufFileReader();
-
- bool open(QString filename, QString filePrefix);
-
- // returns true if the message has be sucessfully parsed
- bool readNext(google::protobuf::Message &message);
-
- private:
- QFile m_file;
- QDataStream m_stream;
-};
-
-#endif // PROTOBUFFILEREADER_H
diff --git a/src/extlibs/er_force_sim/src/core/protobuffilesaver.cpp b/src/extlibs/er_force_sim/src/core/protobuffilesaver.cpp
deleted file mode 100644
index 87a3a8c5db..0000000000
--- a/src/extlibs/er_force_sim/src/core/protobuffilesaver.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/***************************************************************************
- * Copyright 2020 Andreas Wendler *
- * Robotics Erlangen e.V. *
- * http://www.robotics-erlangen.de/ *
- * info@robotics-erlangen.de *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see . *
- ***************************************************************************/
-
-#include "protobuffilesaver.h"
-
-#include
-
-ProtobufFileSaver::ProtobufFileSaver(QString filename, QString filePrefix,
- QObject *parent)
- : QObject(parent),
- m_filename(filename),
- m_filePrefix(filePrefix),
- m_stream(&m_file),
- m_mutex(QMutex::Recursive)
-{
-}
-
-void ProtobufFileSaver::open()
-{
- if (m_file.isOpen())
- {
- return;
- }
- m_file.setFileName(m_filename);
- if (!m_file.open(QIODevice::WriteOnly | QIODevice::Truncate))
- {
- qDebug() << "Could not open path input file for saving";
- return;
- }
-
- // ensure compatibility across qt versions
- m_stream.setVersion(QDataStream::Qt_4_6);
-
- m_stream << QString(m_filePrefix);
- m_stream << (int)0; // file version
-}
-
-void ProtobufFileSaver::saveMessage(const google::protobuf::Message &message)
-{
- QByteArray data;
- data.resize(message.ByteSize());
- if (!message.IsInitialized() || !message.SerializeToArray(data.data(), data.size()))
- {
- return;
- }
-
- QMutexLocker locker(&m_mutex);
- open();
-
- m_stream << data;
-}
diff --git a/src/extlibs/er_force_sim/src/core/protobuffilesaver.h b/src/extlibs/er_force_sim/src/core/protobuffilesaver.h
deleted file mode 100644
index 75d16c10ff..0000000000
--- a/src/extlibs/er_force_sim/src/core/protobuffilesaver.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/***************************************************************************
- * Copyright 2020 Andreas Wendler *
- * Robotics Erlangen e.V. *
- * http://www.robotics-erlangen.de/ *
- * info@robotics-erlangen.de *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see . *
- ***************************************************************************/
-
-#ifndef PROTOBUFFILESAVER_H
-#define PROTOBUFFILESAVER_H
-
-#include
-
-#include
-#include
-#include
-#include
-#include