Skip to content

Commit 976e0d9

Browse files
committed
implementing rl kick in behaviour
1 parent 9677784 commit 976e0d9

5 files changed

Lines changed: 74 additions & 35 deletions

File tree

src/bitbots_behavior/bitbots_blackboard/bitbots_blackboard/capsules/kick_capsule.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from enum import Flag
22
from typing import Optional
33

4+
from geometry_msgs.msg import PoseStamped
45
from rclpy.action import ActionClient
56
from rclpy.callback_groups import ReentrantCallbackGroup
67
from rclpy.duration import Duration
@@ -34,6 +35,7 @@ class WalkKickTargets(Flag):
3435
RIGHT = True
3536

3637
walk_kick_pub: Publisher
38+
rl_kick_pub: Publisher
3739

3840
def __init__(self, node, blackboard):
3941
super().__init__(node, blackboard)
@@ -42,6 +44,7 @@ def __init__(self, node, blackboard):
4244
"""
4345
self.walk_kick_pub = self._node.create_publisher(Bool, "/kick", 1)
4446
# self.connect_dynamic_kick() Do not connect if dynamic_kick is disabled
47+
self.rl_kick_pub = self._node.create_publisher(PoseStamped, "/rl_kick/goal", 1)
4548

4649
def walk_kick(self, target: WalkKickTargets) -> None:
4750
"""
@@ -81,6 +84,13 @@ def dynamic_kick(self, goal: Kick.Goal) -> None:
8184
self.last_goal = goal
8285
self.last_goal_sent = self._node.get_clock().now()
8386

87+
def rl_kick(self, goal_pose: PoseStamped) -> None:
88+
"""
89+
Kick the ball using the RL kick
90+
:param target: Target for the RL kick (e.g. left or right foot)
91+
"""
92+
self.rl_kick_pub.publish(goal_pose)
93+
8494
def __feedback_cb(self, feedback):
8595
self.last_feedback: Kick.Feedback = feedback.feedback
8696
self.last_feedback_received = self._node.get_clock().now()

src/bitbots_behavior/bitbots_body_behavior/bitbots_body_behavior/behavior_dsd/actions/kick_ball.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,39 @@ def perform(self, reevaluate=False):
123123
self._goal_sent = True
124124
else:
125125
self.pop()
126+
127+
128+
class RLKick(AbstractKickAction):
129+
def __init__(self, blackboard, dsd, parameters):
130+
super().__init__(blackboard, dsd, parameters)
131+
132+
self.kick_length = self.blackboard.config["kick_cost_kick_length"]
133+
self.angular_range = self.blackboard.config["kick_cost_angular_range"]
134+
self.max_kick_angle = self.blackboard.config["max_kick_angle"]
135+
self.num_kick_angles = self.blackboard.config["num_kick_angles"]
136+
self.penalty_kick_angle = self.blackboard.config["penalty_kick_angle"]
137+
138+
def perform(self, reevaluate=False):
139+
goal = Kick.Goal()
140+
goal.header.stamp = self.blackboard.node.get_clock().now().to_msg()
141+
goal.header.frame_id = self.blackboard.world_model.base_footprint_frame
142+
143+
ball_u, ball_v = self.blackboard.world_model.get_ball_position_uv()
144+
goal.kick_speed = 1.0
145+
goal.ball_position.x = ball_u
146+
goal.ball_position.y = ball_v
147+
goal.ball_position.z = 0.0
148+
goal.unstable = False
149+
150+
kick_direction = self.blackboard.costmap.get_best_kick_direction(
151+
-self.max_kick_angle,
152+
self.max_kick_angle,
153+
self.num_kick_angles,
154+
self.kick_length,
155+
self.angular_range,
156+
)
157+
158+
goal.kick_direction = quat_from_yaw(kick_direction)
159+
160+
self.blackboard.kick.rl_kick(goal)
161+
self.pop()

src/bitbots_rl_walk/bitbots_rl_walk/real_walk.py renamed to src/bitbots_rl_walk/bitbots_rl_walk/kick.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import numpy as np
2222
import onnxruntime as rt
2323
from ament_index_python import get_package_share_directory
24-
from geometry_msgs.msg import Twist
24+
from geometry_msgs.msg import PoseStamped, Twist
2525
from rclpy.node import Node
2626
from sensor_msgs.msg import Imu, JointState
2727
from transforms3d.euler import euler2mat
@@ -153,18 +153,19 @@
153153
]
154154

155155

156-
class WalkNode(Node):
156+
class KickNode(Node):
157157
"""Node to control the wolfgang humanoid."""
158158

159159
_previous_action: np.ndarray = np.zeros(len(ORDERED_RELEVANT_JOINT_NAMES), dtype=np.float32)
160160
_imu_data: Optional[Imu] = None
161161
_joint_state: Optional[JointState] = None
162162
_cmd_vel: Optional[Twist] = None
163+
_goal_pose: Optional[PoseStamped] = None
163164
_phase: np.ndarray = np.array([0.0, np.pi], dtype=np.float32)
164165
_phase_dt: float
165166

166167
def __init__(self):
167-
super().__init__("reinforcement_learning_walk_inference_node")
168+
super().__init__("reinforcement_learning_kick_inference_node")
168169

169170
# Set sim time parameter to true
170171
# self.set_parameters([
@@ -179,6 +180,7 @@ def __init__(self):
179180
self._imu_sub = self.create_subscription(Imu, "imu/data", self._imu_callback, 10)
180181
self._joint_state_sub = self.create_subscription(JointState, "joint_states", self._joint_state_callback, 10)
181182
self._cmd_vel_sub = self.create_subscription(Twist, "cmd_vel", self._cmd_vel_callback, 10)
183+
self._goal_pose_sub = self.create_subscription(PoseStamped, "goal_pose", self._goal_pose_callback, 10)
182184

183185
self._timer = self.create_timer(CONTROL_DT, self._timer_callback)
184186

@@ -211,6 +213,9 @@ def _joint_state_callback(self, msg: JointState):
211213
def _cmd_vel_callback(self, msg: Twist):
212214
self._cmd_vel = msg
213215

216+
def _goal_pose_callback(self, msg: PoseStamped):
217+
self._goal_pose = msg
218+
214219
def _imu_callback(self, msg: Imu):
215220
self._imu_data = msg
216221

@@ -274,6 +279,18 @@ def _timer_callback(self):
274279

275280
command = np.array([self._cmd_vel.linear.x, self._cmd_vel.linear.y, self._cmd_vel.angular.z], dtype=np.float32)
276281

282+
"""
283+
rel_ball_pos = np.array(
284+
[
285+
self._ball_pos_rel_filter.pose.pose.position.x,
286+
self._ball_pos_rel_filter.pose.pose.position.y,
287+
],
288+
dtype=np.float32,
289+
)
290+
291+
rel_target_pos = np.array([])
292+
"""
293+
277294
obs = np.hstack(
278295
[
279296
gyro, # 3
@@ -283,6 +300,7 @@ def _timer_callback(self):
283300
joint_velocities, # 18
284301
self._previous_action, # 18 # Previous action
285302
phase, # 2
303+
# rel_ball_pos, # 2
286304
]
287305
).astype(np.float32)
288306

@@ -310,7 +328,7 @@ def main():
310328
import rclpy
311329

312330
rclpy.init()
313-
node = WalkNode()
331+
node = KickNode()
314332
rclpy.spin(node)
315333
node.destroy_node()
316334
rclpy.try_shutdown()

src/bitbots_rl_walk/bitbots_rl_walk/walk.py

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,15 @@
2121
import numpy as np
2222
import onnxruntime as rt
2323
from ament_index_python import get_package_share_directory
24-
from geometry_msgs.msg import PoseWithCovarianceStamped, Twist
24+
from geometry_msgs.msg import Twist
2525
from rclpy.node import Node
2626
from sensor_msgs.msg import Imu, JointState
27-
from soccer_vision_3d_msgs.msg import GoalpostArray
2827
from transforms3d.euler import euler2mat
2928
from transforms3d.quaternions import quat2mat
3029

3130
from bitbots_msgs.msg import JointCommand
3231

33-
ONNX_MODEL = os.path.join(get_package_share_directory("bitbots_rl_walk"), "models", "wolfgang_walk_ppo.onnx")
32+
ONNX_MODEL = os.path.join(get_package_share_directory("bitbots_rl_walk"), "models", "wolfgang_kick_ppo.onnx")
3433

3534
PREPARATION_STATE = np.array(
3635
[
@@ -161,8 +160,6 @@ class WalkNode(Node):
161160
_imu_data: Optional[Imu] = None
162161
_joint_state: Optional[JointState] = None
163162
_cmd_vel: Optional[Twist] = None
164-
_ball_pos_rel_filter: Optional[PoseWithCovarianceStamped] = None
165-
_goal_posts_rel: Optional[GoalpostArray] = None
166163
_phase: np.ndarray = np.array([0.0, np.pi], dtype=np.float32)
167164
_phase_dt: float
168165

@@ -182,12 +179,6 @@ def __init__(self):
182179
self._imu_sub = self.create_subscription(Imu, "imu/data", self._imu_callback, 10)
183180
self._joint_state_sub = self.create_subscription(JointState, "joint_states", self._joint_state_callback, 10)
184181
self._cmd_vel_sub = self.create_subscription(Twist, "cmd_vel", self._cmd_vel_callback, 10)
185-
self._ball_pos_rel_filter_sub = self.create_subscription(
186-
PoseWithCovarianceStamped, "ball_position_relative_filtered", self._ball_pos_rel_filter_callback, 10
187-
)
188-
self._goal_posts_rel_sub = self.create_subscription(
189-
GoalpostArray, "goal_posts_relative", self._goal_posts_rel_callback, 10
190-
)
191182

192183
self._timer = self.create_timer(CONTROL_DT, self._timer_callback)
193184

@@ -223,12 +214,6 @@ def _cmd_vel_callback(self, msg: Twist):
223214
def _imu_callback(self, msg: Imu):
224215
self._imu_data = msg
225216

226-
def _ball_pos_rel_filter_callback(self, msg: PoseWithCovarianceStamped):
227-
self._ball_pos_rel_filter = msg
228-
229-
def _goal_posts_rel_callback(self, msg: GoalpostArray):
230-
self._goal_posts_rel = msg
231-
232217
def _timer_callback(self):
233218
"""Timer callback to publish joint commands based on the ONNX policy."""
234219
if self._imu_data is None or self._joint_state is None or self._cmd_vel is None:
@@ -289,18 +274,6 @@ def _timer_callback(self):
289274

290275
command = np.array([self._cmd_vel.linear.x, self._cmd_vel.linear.y, self._cmd_vel.angular.z], dtype=np.float32)
291276

292-
"""
293-
rel_ball_pos = np.array(
294-
[
295-
self._ball_pos_rel_filter.pose.pose.position.x,
296-
self._ball_pos_rel_filter.pose.pose.position.y,
297-
],
298-
dtype=np.float32,
299-
)
300-
301-
rel_target_pos = np.array([])
302-
"""
303-
304277
obs = np.hstack(
305278
[
306279
gyro, # 3
@@ -310,7 +283,6 @@ def _timer_callback(self):
310283
joint_velocities, # 18
311284
self._previous_action, # 18 # Previous action
312285
phase, # 2
313-
# rel_ball_pos, # 2
314286
]
315287
).astype(np.float32)
316288

src/bitbots_rl_walk/setup.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
data_files=[
1010
("share/ament_index/resource_index/packages", ["resource/" + package_name]),
1111
("share/" + package_name, ["package.xml"]),
12-
("share/" + package_name + "/models", ["models/wolfgang_kick_ppo.onnx"]),
12+
(
13+
"share/" + package_name + "/models",
14+
["models/wolfgang_policy.onnx", "models/wolfgang_walk_ppo.onnx", "models/wolfgang_kick_ppo.onnx"],
15+
),
1316
],
1417
install_requires=["setuptools"],
1518
zip_safe=True,

0 commit comments

Comments
 (0)