Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
48d852d
add prototype dataflow of whistle detection
val-ba Feb 28, 2026
cbe8f5f
add whistle detector package
val-ba Feb 28, 2026
cefd8ca
added publishers for gamecontroller response with dynamic data
cleWu03 Mar 2, 2026
0757d16
update pixi.toml
cleWu03 Mar 5, 2026
54335cf
pixi toml update 2.0
cleWu03 Mar 5, 2026
68a3652
pixi toml upfate 3.0
cleWu03 Mar 5, 2026
7ff2541
put project whistle detection code into whistle detector node
val-ba Mar 5, 2026
06b2224
add model to share in setup py
val-ba Mar 5, 2026
dd78ca2
game_state_capsule updated
cleWu03 Mar 5, 2026
9f3d3f7
integration of new gamestate msg in behavior, secondary state is stil…
cleWu03 Mar 5, 2026
574895f
refactor(game_controller): only send ball `PointStamped`
texhnolyze Mar 9, 2026
3be6547
fix wrong package structure
val-ba Mar 10, 2026
9538674
fix package naming
val-ba Mar 10, 2026
60b3fce
add whistle detection based on frequency bands
val-ba Mar 10, 2026
3d3373f
add launch files
val-ba Mar 10, 2026
1a3eef4
add plugin dir for pipewire
val-ba Mar 10, 2026
04457bf
update dsd for whistle detection and decision
val-ba Mar 10, 2026
bf5c422
added publishers for gamecontroller response with dynamic data
cleWu03 Mar 2, 2026
9d0a396
update pixi.toml
cleWu03 Mar 5, 2026
bb496bc
pixi toml update 2.0
cleWu03 Mar 5, 2026
f59771f
pixi toml upfate 3.0
cleWu03 Mar 5, 2026
47d13fb
game_state_capsule updated
cleWu03 Mar 5, 2026
9bfb6df
integration of new gamestate msg in behavior, secondary state is stil…
cleWu03 Mar 5, 2026
1c162a6
refactor(game_controller): only send ball `PointStamped`
texhnolyze Mar 9, 2026
056339b
added secondary state stuff to Behaviour
cleWu03 Mar 10, 2026
e696382
Merge branch 'Gamecontroller-update-for-HSL' of https://github.com/bi…
cleWu03 Mar 10, 2026
bb7d064
stopped from game_controller
cleWu03 Mar 10, 2026
d97d0a9
fix wrong anming of capsule in whistle decision
val-ba Mar 10, 2026
1ae1ac2
fix wrong placement of launch file
val-ba Mar 10, 2026
47da9a5
create lib dir
val-ba Mar 10, 2026
f9418d4
git subrepo clone git@github.com:ros-drivers/audio_common.git src/lib/
val-ba Mar 10, 2026
e4cd28e
remove lib
val-ba Mar 10, 2026
a7021ab
git subrepo clone git@github.com:mgonzs13/audio_common.git src/lib
val-ba Mar 10, 2026
e1de673
Merge branch 'main' into feature/whistle_detection
val-ba Mar 10, 2026
247fead
update the audio launch
val-ba Mar 10, 2026
8e6da69
feat(game_controller_hsl): finalize implementation of base states
texhnolyze Mar 10, 2026
bce597e
fix against falling when in "stopped" state
cleWu03 Mar 11, 2026
5e668ed
OUR in dsd Tree for all secondaryStateDeciders
cleWu03 Mar 11, 2026
d747566
fix audio launch script
val-ba Mar 11, 2026
6214758
Merge branch 'main' into feature/whistle_detection
val-ba Mar 11, 2026
b5a984a
simplify audio.launch
val-ba Mar 11, 2026
ca26560
add dependencies
val-ba Mar 11, 2026
f28f62b
fix: dont include `/src/game_controller_hsl`
texhnolyze Mar 11, 2026
7b97ed1
Merge branch 'feature/whistle_detection' into go-first-game
texhnolyze Mar 11, 2026
ca679c0
fix idea for working rival freekicks
cleWu03 Mar 11, 2026
3c23b0c
Merge branch 'Gamecontroller-update-for-HSL' of https://github.com/bi…
cleWu03 Mar 11, 2026
3d48999
Merge branch 'main' into Gamecontroller-update-for-HSL
texhnolyze Mar 11, 2026
9dd4bbd
Merge branch 'Gamecontroller-update-for-HSL' into go-first-game
texhnolyze Mar 11, 2026
b5aa180
update ports and target ip for game
val-ba Mar 11, 2026
55cbdfd
Merge branch 'Gamecontroller-update-for-HSL' of github.com:bit-bots/b…
val-ba Mar 11, 2026
7671685
fixing freekick problem
cleWu03 Mar 11, 2026
ea58f97
Merge branch 'Gamecontroller-update-for-HSL' of github.com:bit-bots/b…
val-ba Mar 11, 2026
63d6e0d
dsd version ohne Kommentare
cleWu03 Mar 11, 2026
e6e26f5
seg correction
cleWu03 Mar 11, 2026
984004f
add new field config and adjust default field in launch files
confusedlama Mar 11, 2026
110ce07
Merge branch 'Gamecontroller-update-for-HSL' of github.com:bit-bots/b…
confusedlama Mar 11, 2026
f09b5f6
hcm fix
cleWu03 Mar 11, 2026
6d8768c
remove unnecessary launch of whistle detection in head mover test
val-ba Mar 11, 2026
5b9fe7c
fix: temporarily add `python3-construct` for `game_controller_hsl`
texhnolyze Mar 11, 2026
a603495
fix(teamplayer): disable tts as it crashes
texhnolyze Mar 11, 2026
5cfacac
feat(teamcom): add debug message about proto sizes
texhnolyze Mar 11, 2026
6246dfb
remove command in setup.py
val-ba Mar 11, 2026
4100edf
move whislte detector to misc and add extra launch param
val-ba Mar 11, 2026
215848a
add medium field config
confusedlama Mar 11, 2026
e90daed
git subrepo clone git@github.com:bit-bots/game_controller_hsl.git src…
val-ba Mar 11, 2026
6684ae3
Merge branch 'Gamecontroller-update-for-HSL' into go-first-game
texhnolyze Mar 11, 2026
dd799f2
extrinsic calibration amy
jaagut Mar 11, 2026
33092c0
fix(bio_ik): do not use gradient descent solver
texhnolyze Mar 11, 2026
c30084e
Merge branch 'Gamecontroller-update-for-HSL' into go-first-game
val-ba Mar 11, 2026
7834eaf
fix new field map scaling
confusedlama Mar 11, 2026
2167482
create audio_common folder in lib
val-ba Mar 11, 2026
ae5c91b
fix for falling after stop state, is now integrated later in hcm and …
cleWu03 Mar 11, 2026
ce9beaf
fix(git-subrepo): add `git-subrepo` to pixi
texhnolyze Mar 11, 2026
3fe2b25
git subrepo pull src/lib/game_controller_hsl --force
texhnolyze Mar 11, 2026
a00690f
fix(deploy): use taskset to run build on 10 cpu cores
texhnolyze Mar 11, 2026
3da6740
fix(behavior): change BodyBehavior back to entrypoint (`-->`)
texhnolyze Mar 11, 2026
328a9df
jack camera calibration
jaagut Mar 11, 2026
2781b79
Merge branch 'Gamecontroller-update-for-HSL' of github.com:bit-bots/b…
jaagut Mar 11, 2026
e173c03
Merge branch 'Gamecontroller-update-for-HSL' into go-first-game
val-ba Mar 11, 2026
0666c53
Merge branch 'feature/whistle_detection' into go-first-game
val-ba Mar 11, 2026
903670e
be more conservative with whistle threshold
val-ba Mar 11, 2026
f103e55
fix(pre-commit): always exclude `src/lib`
texhnolyze Mar 11, 2026
1813faa
git subrepo clone (merge) git@github.com:bit-bots/bio_ik.git src/lib/…
texhnolyze Mar 11, 2026
31ca43d
Merge branch 'Gamecontroller-update-for-HSL' into feature/whistle_det…
texhnolyze Mar 12, 2026
32cb288
calibrate amy
confusedlama Mar 12, 2026
e91d550
calibrate donna
confusedlama Mar 12, 2026
054d65f
remove bioik pixi dep
jaagut Mar 12, 2026
ee97843
set default field to german_open_2026
jaagut Mar 12, 2026
9a2135b
jack trunk offset because he could not walk backwards
jaagut Mar 12, 2026
a070910
fix (whistle detection disabled localization through movement)
cleWu03 Mar 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ fabric.properties
### ROS template
build/
bin/
lib/
msg_gen/
srv_gen/
msg/*Action.msg
Expand Down
10 changes: 7 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
exclude: |
^src/lib/|
^src/bitbots_team_communication/bitbots_team_communication/bitbots_team_communication/RobocupProtocol/

repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.6
Expand All @@ -6,15 +10,17 @@ repos:
args:
- "--fix"
- "--exit-non-zero-on-fix"
- "--exclude=src/lib/**"
- id: ruff-format
args:
- "--exclude=src/lib/**"
- repo: https://github.com/pocc/pre-commit-hooks
rev: v1.3.5
hooks:
- id: clang-format
args:
- "-i"
- id: cppcheck
exclude: &exclude_robocup_protocol ^src/bitbots_team_communication/bitbots_team_communication/bitbots_team_communication/RobocupProtocol/
args:
- "--inline-suppr"
- "--suppress=missingIncludeSystem"
Expand All @@ -28,13 +34,11 @@ repos:
hooks:
- id: cmake-format
- id: cmake-lint
exclude: *exclude_robocup_protocol
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: check-merge-conflict
- id: check-toml
- id: check-xml
- id: check-yaml
exclude: *exclude_robocup_protocol
- id: detect-private-key
3,212 changes: 1,573 additions & 1,639 deletions pixi.lock

Large diffs are not rendered by default.

15 changes: 12 additions & 3 deletions pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ authors = ["Florian Vahl <7vahl@informatik.uni-hamburg.de>"]
channels = [
"https://data.bit-bots.de/conda/", # For self hosted ROS / robostack packages
"https://data.bit-bots.de/conda-misc/output/", # For self hosted misc (non-ROS, neural network weights, ...) packages
"robostack-jazzy", # Robostack jazzy channel for ROS packages
"robostack-jazzy", # Robostack jazzy channel for ROS packages
"conda-forge" # General conda-forge channel
]
name = "bitbots_main"
Expand Down Expand Up @@ -160,12 +160,11 @@ ros-jazzy-soccer-vision-3d-rviz-markers = ">=1.0.0,<2"
ros-jazzy-soccer-vision-3d-msgs = ">=1.0.0,<2"
ros-jazzy-soccer-vision-attribute-msgs = ">=1.0.0,<2"
ros-jazzy-rot-conv = ">=1.1.0,<2"
ros-jazzy-bio-ik = ">=2.0.0,<3"
#ros-jazzy-bio-ik = ">=2.0.0,<3"
ros-jazzy-bio-ik-msgs = ">=0.0.0,<0.0.1"
ros-jazzy-biped-interfaces = ">=0.0.0,<0.0.1"
ros-jazzy-bitbots-tf-buffer = ">=1.0.0,<2"
ros-jazzy-ros2-python-extension = ">=1.0.0,<2"
ros-jazzy-audio-common = ">=0.3.15,<0.4"
ros-jazzy-dynamic-stack-decider = ">=0.5.3,<0.6"
ros-jazzy-dynamic-stack-decider-visualization = ">=0.2.1,<0.3"
ros-jazzy-game-controller-hl = ">=1.1.0,<2"
Expand Down Expand Up @@ -197,6 +196,12 @@ setuptools = "==68.1.2" # Pinning setuptools to avoid issues with colcon build
git = ">=2.52.0,<3" # Otherwise the system git might be used causing ABI issues
curl = ">=8.17.0,<9"
make = ">=4.4.1,<5" # To avoid issues in the CI
libflac = "==1.4.3"
portaudio = ">=19.7.0,<20"
ros-jazzy-ament-cmake-clang-format = ">=0.17.3,<0.18"
ros-jazzy-rosidl-runtime-c = ">=4.6.7,<5"
alsa-plugins = ">=1.2.12,<2"
git-subrepo = ">=0.4.9,<0.5"

[feature.ros.target.linux-64.dependencies]
# For now Webots is only packaged for x86-64 Linux
Expand All @@ -206,9 +211,11 @@ webots = ">=2022b,<2023a"
clang-format = ">=21.1.0,<22"
cppcheck = ">=2.18.3,<3"
pre-commit = ">=4.4.0,<5"
git-subrepo = ">=0.4.9,<0.5"

[feature.ros.pypi-dependencies]
# These are are pypi dependencies needed for our ROS 2 packages
construct = ">=2.10.56, <3"
syrupy = ">=5.0.0, <6"
exhale = ">=0.3.7, <0.4"
mycroft-mimic3-tts = ">=0.2.4, <0.3"
Expand All @@ -233,6 +240,7 @@ RMW_IMPLEMENTATION = "rmw_cyclonedds_cpp"
COLCON_LOG_LEVEL = "30"
PYTHONWARNINGS="ignore:::setuptools.command.install,ignore:::setuptools.command.easy_install,ignore:::pkg_resources,ignore:easy_install command is deprecated,ignore:setup.py install is deprecated"
WEBOTS_HOME = "$CONDA_PREFIX/share/webots"
ALSA_PLUGIN_DIR = "/usr/lib/x86_64-linux-gnu/alsa-lib"

[feature.ros.activation]
scripts = [
Expand All @@ -244,3 +252,4 @@ scripts = [
default = ["ros", "format"] # Full development environment (excluding robot-only deps)
format = ["format"] # Format only environment
robot = ["ros", "format", "robot"] # Robot environment with additional robot-only dependencies

2 changes: 1 addition & 1 deletion scripts/deploy/tasks/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def _build(self, connections: Group) -> GroupResult:
:return: The results of the task.
"""
print_debug("Building packages")
cmd = f"cd {self._remote_workspace} && pixi run build {self._package}"
cmd = f"cd {self._remote_workspace} && chrt -r 1 taskset -c 0-9 pixi run build {self._package}"

print_debug(f"Calling '{cmd}'")
try:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from typing import Optional

from bitbots_utils.utils import get_parameters_from_other_node
from game_controller_hl_interfaces.msg import GameState
from game_controller_hsl_interfaces.msg import GameState
from std_msgs.msg import Bool
from rclpy.time import Time

from bitbots_blackboard.capsules import AbstractBlackboardCapsule

Expand All @@ -12,33 +14,46 @@ class GameStatusCapsule(AbstractBlackboardCapsule):
def __init__(self, node, blackboard=None):
super().__init__(node, blackboard)
self.team_id: int = get_parameters_from_other_node(self._node, "parameter_blackboard", ["team_id"])["team_id"]
self.own_id: int = get_parameters_from_other_node(self._node, "parameter_blackboard", ["bot_id"])["bot_id"]
self.own_id: int = get_parameters_from_other_node(self._node, "parameter_blackboard", ["bot_id"])["bot_id"]
self.gamestate = GameState()
self.last_update: float = 0.0
self.unpenalized_time: float = 0.0
self.last_goal_from_us_time = -86400.0
self.last_goal_time = -86400.0
self.free_kick_kickoff_team: Optional[bool] = None
self.last_timestep_whistle_detected: Time = self._node.get_clock().now()
self.game_controller_stop: bool = False
# publish stopped msg for hcm
self.stop_pub = node.create_publisher(Bool, "game_controller/stop_msg", 1)

def get_gamestate(self) -> int:
return self.gamestate.game_state
def get_game_state(self) -> int:
# Init, ready, set, playing, finished
return self.gamestate.main_state

def get_secondary_state(self) -> int:
return self.gamestate.secondary_state
def get_game_phase(self) -> int:
# Timeout, Normal, Extratime, Penaltyshoot
return self.gamestate.game_phase

def get_secondary_state_mode(self) -> int:
return self.gamestate.secondary_state_mode
def get_set_play(self) -> int:
# None, Direct Freekick, Indirect Freekick, Penalty, Throw in, Goalkick, Cornerkick,
return self.gamestate.set_play

def get_secondary_team(self) -> int:
return self.gamestate.secondary_state_team
# Team ID, wer in set Play den Ball hat
return self.gamestate.kicking_team

def has_kickoff(self) -> bool:
return self.gamestate.has_kick_off
# vegelcih mit eigener Teamnummer
return self.gamestate.kicking_team == self.team_id

def is_stopped(self) -> bool:
return self.gamestate.stopped

def has_penalty_kick(self) -> bool:
return (
self.gamestate.secondary_state == GameState.STATE_PENALTYKICK
or self.gamestate.secondary_state == GameState.STATE_PENALTYSHOOT
) and self.gamestate._secondary_state_team == self.team_id
self.gamestate.set_play == GameState.SET_PLAY_PENALTY_KICK and self.gamestate.kicking_team == self.team_id
)

def get_our_goals(self) -> int:
return self.gamestate.own_score
Expand All @@ -55,26 +70,17 @@ def get_seconds_since_any_goal(self) -> float:
def get_seconds_remaining(self) -> float:
# Time from the message minus time passed since receiving it
return max(
self.gamestate.seconds_remaining - (self._node.get_clock().now().nanoseconds / 1e9 - self.last_update), 0.0
self.gamestate.secs_remaining - (self._node.get_clock().now().nanoseconds / 1e9 - self.last_update), 0.0
)

def get_secondary_seconds_remaining(self) -> float:
"""Seconds remaining for things like kickoff"""
# Time from the message minus time passed since receiving it
return max(
self.gamestate.secondary_seconds_remaining
- (self._node.get_clock().now().nanoseconds / 1e9 - self.last_update),
self.gamestate.secondary_time - (self._node.get_clock().now().nanoseconds / 1e9 - self.last_update),
0.0,
)

def get_seconds_since_last_drop_ball(self) -> Optional[float]:
"""Returns the seconds since the last drop in"""
if self.gamestate.drop_in_time == -1:
return None
else:
# Time from the message plus seconds passed since receiving it
return self.gamestate.drop_in_time + (self._node.get_clock().now().nanoseconds / 1e9 - self.last_update)

def get_seconds_since_unpenalized(self) -> float:
return self._node.get_clock().now().nanoseconds / 1e9 - self.unpenalized_time

Expand All @@ -87,9 +93,6 @@ def received_gamestate(self) -> bool:
def get_team_id(self) -> int:
return self.team_id

def get_red_cards(self) -> int:
return self.gamestate.team_mates_with_red_card

def gamestate_callback(self, gamestate_msg: GameState) -> None:
if self.gamestate.penalized and not gamestate_msg.penalized:
self.unpenalized_time = self._node.get_clock().now().nanoseconds / 1e9
Expand All @@ -101,21 +104,39 @@ def gamestate_callback(self, gamestate_msg: GameState) -> None:
if gamestate_msg.rival_score > self.gamestate.rival_score:
self.last_goal_time = self._node.get_clock().now().nanoseconds / 1e9

self.game_controller_stop = gamestate_msg.stopped

self.stop_pub.publish(Bool(data=self.game_controller_stop))

"""Anstoß im Falle von Overtime jetzt erstmal nicht genauer geregelt
if (
gamestate_msg.secondary_state_mode == 2
and self.gamestate.secondary_state_mode != 2
and gamestate_msg.game_state == GameState.GAMESTATE_PLAYING
gamestate_msg.main_state == GameState.STATE_SET
and self.gamestate.setPlay != 2
and gamestate_msg.state == GameState.STATE_PLAYING
gamestate_msg.main_state == GameState.STATE_SET
and self.gamestate.setPlay != 2
and gamestate_msg.state == GameState.STATE_PLAYING
):
# secondary action is now executed but we will not see this in the new messages.
# it will look like a normal kick off, but we need to remember that this is some sort of free kick
# we set the kickoff value accordingly, then we will not be allowed to move if it is a kick for the others
self.free_kick_kickoff_team = gamestate_msg.secondary_state_team
self.free_kick_kickoff_team = gamestate_msg.kicking_team


if gamestate_msg.secondary_state_mode != 2 and gamestate_msg.secondary_seconds_remaining == 0:
if gamestate_msg.set_play != 2 and gamestate_msg.secondary_time == 0:
self.free_kick_kickoff_team = gamestate_msg.kicking_team


if gamestate_msg.set_play != 2 and gamestate_msg.secondary_time == 0:
self.free_kick_kickoff_team = None



if self.free_kick_kickoff_team is not None:
gamestate_msg.has_kick_off = self.free_kick_kickoff_team == self.team_id

"""
self.last_update = self._node.get_clock().now().nanoseconds / 1e9
self.gamestate = gamestate_msg

def whistle_detection_callback(self, _) -> None: # MSG type is assumed to be bool for now, prototyping
self.last_timestep_whistle_detected = self._node.get_clock().now() # This stays true after the first whistle detection which is incorrect
2 changes: 1 addition & 1 deletion src/bitbots_behavior/bitbots_blackboard/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<build_depend>bitbots_docs</build_depend>
<depend>bitbots_tf_buffer</depend>
<depend>bitbots_utils</depend>
<depend>game_controller_hl_interfaces</depend>
<depend>game_controller_hsl_interfaces</depend>
<depend>python3-numpy</depend>
<depend>rclpy</depend>
<depend>ros2_numpy</depend>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from bitbots_blackboard.body_blackboard import BodyBlackboard
from dynamic_stack_decider.abstract_decision_element import AbstractDecisionElement
from game_controller_hl_interfaces.msg import GameState
from game_controller_hsl_interfaces.msg import GameState


class GameStateDecider(AbstractDecisionElement):
Expand All @@ -16,18 +16,28 @@ def perform(self, reevaluate=False):
:return:
"""

game_state_number = self.blackboard.gamestate.get_gamestate()
game_state_number = self.blackboard.gamestate.get_game_state()
is_stopped = self.blackboard.gamestate.is_stopped()
# todo this is a temporary hack to make GUI work
if game_state_number == GameState.GAMESTATE_INITIAL:
if is_stopped:
return "STOPPED"
elif game_state_number == GameState.STATE_INITIAL:
return "INITIAL"
elif game_state_number == GameState.GAMESTATE_READY:
elif game_state_number == GameState.STATE_READY:
return "READY"
elif game_state_number == GameState.GAMESTATE_SET:
elif game_state_number == GameState.STATE_SET:
return "SET"
elif game_state_number == GameState.GAMESTATE_PLAYING:
elif game_state_number == GameState.STATE_PLAYING:
return "PLAYING"
elif game_state_number == GameState.GAMESTATE_FINISHED:
elif game_state_number == GameState.STATE_FINISHED:
return "FINISHED"
elif game_state_number == GameState.STATE_STANDBY:
return "STANDBY"
else:
# This should never happen, but all cases required string response
# as we do not get any stack trace otherwise
self.blackboard.node.get_logger().error(f"Received unknown game state number: {game_state_number}")
return "UNKNOWN"

def get_reevaluate(self):
"""
Expand Down

This file was deleted.

Loading
Loading