Skip to content

Commit 5bdbdba

Browse files
cleWu03texhnolyze
authored andcommitted
fix(whistle_detection): correctly localize during STATE_SET + whistle
which happends, when switching from `STATE_SET` to `STATE_PLAYING` by whistle, but the GameController only delivers the `STATE_PLAYING` after the whistle detection "cooldown".
1 parent 83b1b68 commit 5bdbdba

9 files changed

Lines changed: 59 additions & 16 deletions

File tree

src/bitbots_behavior/bitbots_blackboard/bitbots_blackboard/capsules/game_status_capsule.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from bitbots_utils.utils import get_parameters_from_other_node
44
from game_controller_hsl_interfaces.msg import GameState
5+
from rclpy.time import Time
56
from std_msgs.msg import Bool
67

78
from bitbots_blackboard.capsules import AbstractBlackboardCapsule
@@ -20,7 +21,7 @@ def __init__(self, node, blackboard=None):
2021
self.last_goal_from_us_time = -86400.0
2122
self.last_goal_time = -86400.0
2223
self.free_kick_kickoff_team: Optional[bool] = None
23-
self.whistle_detected: bool = False
24+
self.last_timestep_whistle_detected: Time = self._node.get_clock().now()
2425
self.game_controller_stop: bool = False
2526
# publish stopped msg for hcm
2627
self.stop_pub = node.create_publisher(Bool, "game_controller/stop_msg", 1)
@@ -129,5 +130,5 @@ def gamestate_callback(self, gamestate_msg: GameState) -> None:
129130
self.last_update = self._node.get_clock().now().nanoseconds / 1e9
130131
self.gamestate = gamestate_msg
131132

132-
def whistle_detection_callback(self, msg) -> None:
133-
self.whistle_detected = msg.data
133+
def whistle_detection_callback(self, _) -> None:
134+
self.last_timestep_whistle_detected = self._node.get_clock().now()

src/bitbots_behavior/bitbots_body_behavior/bitbots_body_behavior/behavior_dsd/decisions/whistle_detected.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ class WhistleDetected(AbstractDecisionElement):
77

88
def __init__(self, blackboard, dsd, parameters):
99
super().__init__(blackboard, dsd, parameters)
10-
self.bb = blackboard
11-
self.bb.gamestate.whistle_detected = False
10+
self.blackboard = blackboard
11+
self.last_timestep_whistle_detected = self.blackboard.gamestate.last_timestep_whistle_detected
1212

1313
def perform(self, reevaluate=False):
14-
if self.bb.gamestate.whistle_detected:
15-
return "YES"
16-
return "NO"
14+
if self.last_timestep_whistle_detected == self.blackboard.gamestate.last_timestep_whistle_detected:
15+
return "NOT_DETECTED"
16+
return "DETECTED"
1717

1818
def get_reevaluate(self):
1919
return True

src/bitbots_behavior/bitbots_body_behavior/bitbots_body_behavior/behavior_dsd/main.dsd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ $IsPenalized
154154
NOT_DONE --> @ChangeAction + action:waiting + r:false, @LookAtFieldFeatures + r:false, @Stand + duration:2
155155
DONE --> #PositioningReady
156156
SET --> $WhistleDetected
157-
YES --> #PlayingBehavior
158-
NO --> $SecondaryStateDecider
157+
DETECTED --> #PlayingBehavior
158+
NOT_DETECTED --> $SecondaryStateDecider
159159
PENALTYSHOOT --> $SecondaryStateTeamDecider
160160
OUR --> @Stand + duration:0.1 + r:false, @DeactivateHCM + r:false, @LookForward + r:false, @PlayAnimationInitInSim + r:false, @GetWalkready + r:false, @Stand // we need to also see the goalie
161161
OTHER --> $BallSeen

src/bitbots_behavior/bitbots_body_behavior/bitbots_body_behavior/body_behavior.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from rclpy.experimental.events_executor import EventsExecutor
1212
from rclpy.node import Node
1313
from soccer_vision_3d_msgs.msg import RobotArray
14-
from std_msgs.msg import Bool
14+
from std_msgs.msg import Empty
1515

1616
from bitbots_body_behavior import behavior_dsd
1717
from bitbots_msgs.msg import RobotControlState, TeamData
@@ -77,7 +77,7 @@ def __init__(self, node: Node):
7777
callback_group=MutuallyExclusiveCallbackGroup(),
7878
)
7979
node.create_subscription(
80-
Bool,
80+
Empty,
8181
"whistle_detected",
8282
blackboard.gamestate.whistle_detection_callback,
8383
qos_profile=1,

src/bitbots_misc/bitbots_whistle_detector/bitbots_whistle_detector/whistle_detector.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
from rclpy.experimental.events_executor import EventsExecutor
77
from rclpy.node import Node
88
from rclpy.qos import qos_profile_sensor_data
9-
from std_msgs.msg import Bool
9+
from std_msgs.msg import Empty
1010

1111

1212
class WhistleDetector(Node):
1313
def __init__(self) -> None:
1414
super().__init__("whistle_detector")
1515
self.logger = self.get_logger()
1616

17-
self.whistle_publisher = self.create_publisher(Bool, "whistle_detected", 1)
17+
self.whistle_publisher = self.create_publisher(Empty, "whistle_detected", 1)
1818

1919
self.audio_buffer = np.array([], dtype=np.float32)
2020
self.sample_rate = 16000
@@ -45,7 +45,7 @@ def process_audio(self) -> None:
4545
whistle_detected = self.detect_whistle(audio, self.sample_rate)
4646

4747
if whistle_detected:
48-
msg = Bool(data=True)
48+
msg = Empty()
4949
self.whistle_publisher.publish(msg)
5050

5151
def detect_whistle(self, audio, sample_rate):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from bitbots_localization_handler.localization_dsd.decisions import AbstractLocalizationDecisionElement
2+
from bitbots_localization_handler.localization_dsd.localization_blackboard import LocalizationBlackboard
3+
4+
5+
class WhistleDetected(AbstractLocalizationDecisionElement):
6+
def __init__(self, blackboard, dsd, parameters):
7+
super().__init__(blackboard, dsd, parameters)
8+
self.blackboard: LocalizationBlackboard
9+
self.last_timestep_whistle_detected = self.blackboard.last_timestep_whistle_detected
10+
11+
def perform(self, reevaluate=False):
12+
"""
13+
Checks if a whistle was detected
14+
"""
15+
16+
if self.last_timestep_whistle_detected == self.blackboard.last_timestep_whistle_detected:
17+
return "NOT_DETECTED"
18+
else:
19+
return "DETECTED"
20+
21+
def get_reevaluate(self):
22+
"""
23+
Game state can change during the game
24+
"""
25+
return True

src/bitbots_navigation/bitbots_localization_handler/bitbots_localization_handler/localization_dsd/localization.dsd

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,7 @@ $GettingUpState
2222
NO --> $InitialToReady
2323
YES --> @InitSide, @DoNothing
2424
NO --> $GameStateDecider
25-
SET --> #InitSet
25+
SET --> $WhistleDetected
26+
NOT_DETECTED --> #InitSet
27+
DETECTED --> @DoNothing
2628
ELSE --> @DoNothing

src/bitbots_navigation/bitbots_localization_handler/bitbots_localization_handler/localization_dsd/localization_blackboard.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from jaxtyping import Float
1111
from rclpy.duration import Duration
1212
from rclpy.node import Node
13+
from rclpy.time import Time
1314
from ros2_numpy import numpify
1415
from sensor_msgs.msg import Imu
1516
from tf2_geometry_msgs import TransformStamped
@@ -69,6 +70,9 @@ def __init__(self, node: Node):
6970
self.last_init_action_type: Optional[type] = None
7071
self.last_init_odom_transform: TransformStamped | None = None
7172

73+
# Last time we have detected a whistle
74+
self.last_timestep_whistle_detected: Time = self.node.get_clock().now()
75+
7276
def _callback_pose(self, msg: PoseWithCovarianceStamped):
7377
self.robot_pose = msg
7478

@@ -122,3 +126,6 @@ def get_localization_yaw(self) -> float:
122126
if self.robot_pose is None:
123127
return 0.0
124128
return quat2euler(xyzw2wxyz(numpify(self.robot_pose.pose.pose.orientation)), axes="szxy")[0]
129+
130+
def whistle_detection_callback(self, _):
131+
self.last_timestep_whistle_detected = self.node.get_clock().now()

src/bitbots_navigation/bitbots_localization_handler/bitbots_localization_handler/localization_handler.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from rclpy.experimental.events_executor import EventsExecutor
1010
from rclpy.node import Node
1111
from sensor_msgs.msg import Imu
12+
from std_msgs.msg import Empty
1213

1314
from bitbots_localization_handler import localization_dsd
1415
from bitbots_localization_handler.localization_dsd.localization_blackboard import LocalizationBlackboard
@@ -48,6 +49,13 @@ def init(node: Node):
4849
node.create_subscription(
4950
Imu, "/imu/data", blackboard._callback_imu, 1, callback_group=MutuallyExclusiveCallbackGroup()
5051
)
52+
node.create_subscription(
53+
Empty,
54+
"whistle_detected",
55+
blackboard.whistle_detection_callback,
56+
qos_profile=1,
57+
callback_group=MutuallyExclusiveCallbackGroup(),
58+
)
5159

5260
return dsd
5361

0 commit comments

Comments
 (0)