Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
99 changes: 55 additions & 44 deletions ball.py
Original file line number Diff line number Diff line change
@@ -1,67 +1,78 @@
import os
import pandas as pd
import math
def track_ball_position(udp, receive_packet, receive_game_controller_signal, stop_event, debug=False, sock=None):
balls_position = []
packet = receive_packet(udp)
frame = packet.detection
def track_ball_position(udp, receive_packet, receive_game_controller_signal, stop_event, debug=False, sock=None): # ボール位置の追跡
balls_position = [] # ボール位置を保存するリスト
packet = receive_packet(udp) # パケットを受信
frame = packet.detection # フレームを取得
if debug:
print("frame: ", frame)
print("frame: ", frame) # デバッグ用にフレームを表示
if frame:
balls = frame.balls
balls = frame.balls # ボールのリストを取得
if balls:
ball = balls[0]
ball = balls[0] # 最初のボールを取得
# sockを引数で受け取るか、グローバルから参照
state = receive_game_controller_signal(sock, stop_event)
balls_position.append([int(ball.x), int(ball.y), state,receive_packet(udp).detection.frame_number])
state = receive_game_controller_signal(sock, stop_event) # ゲームコントローラーの信号を受信
balls_position.append([int(ball.x), int(ball.y), state, frame.frame_number]) # ボール位置を保存
return balls_position

def store_ball_position(udp, receive_packet, receive_game_controller_signal, stop_event, path, debug=False, sock=None):
while not stop_event.is_set():
def store_ball_position(udp, receive_packet, receive_game_controller_signal, stop_event, path, debug=False, sock=None): # ボール位置の保存
while not stop_event.is_set(): # スレッドが停止されるまでループ
try:
ball_position = track_ball_position(udp, receive_packet, receive_game_controller_signal, stop_event, debug,sock)
ballpojiPath = os.path.join(path, "ball_position.csv")
ball_position = track_ball_position(udp, receive_packet, receive_game_controller_signal, stop_event, debug,sock) # ボール位置を追跡
ball_position_path = os.path.join(path, "ball_position.csv") # ボール位置のCSVファイルパス
if not os.path.isdir(path):
os.mkdir(path)
os.mkdir(path) # 出力先ディレクトリが存在しない場合は作成
if ball_position:
df = pd.DataFrame(ball_position, columns=["x", "y", "state","frame_number"])
if not os.path.exists(ballpojiPath):
df.to_csv(ballpojiPath, mode='w', header=True, index=False)
df = pd.DataFrame(ball_position, columns=["x", "y", "state","frame_number"]) # ボール位置のデータフレームを作成
if not os.path.exists(ball_position_path):
df.to_csv(ball_position_path, mode='w', header=True, index=False) # ボール位置のCSVファイルが存在しない場合は新規作成
else:
df.to_csv(ballpojiPath, mode='a', header=False, index=False)
df.to_csv(ball_position_path, mode='a', header=False, index=False) # 存在する場合は追記
if debug:
print("ball_position: ", ball_position)
print("ball_position: ", ball_position) # デバッグ用にボール位置を表示
print("\n")
except KeyboardInterrupt:
except KeyboardInterrupt: # キーボード割り込みで終了
break

def ball_velocity(udp, receive_packet, receive_game_controller_signal, stop_event, path, debug, sock):
ball_posi = []
while not stop_event.is_set():
def ball_velocity(udp, receive_packet, receive_game_controller_signal, stop_event, path, debug=False, sock=None): # ボール速度の計算
ball_posi = [] # 過去のボール位置のリスト
while not stop_event.is_set(): # スレッドが停止されるまでループ
try:

ball_position = track_ball_position(udp, receive_packet, receive_game_controller_signal, stop_event, debug, sock)
ball_position = track_ball_position(udp, receive_packet, receive_game_controller_signal, stop_event, debug, sock) # ボール位置を追跡
if ball_position:
ball_posi.append(ball_position[0]) # 最新データを追加
# print("ball_position: ", ball_position)
print("---------------------------------\n")
print("ball_position[0]: ", ball_position[0])
print("---------------------------------\n")
# print("ball_posi: ", ball_posi)
print("---------------------------------\n")
print("ball_posi[0]: ", ball_posi[0])
if len(ball_posi) == 2:
x1, y1, state1, frame1 = ball_posi[0]
x2, y2, state2, frame2 = ball_posi[1]
dt = (frame2 - frame1) * (1/60)
vx = (x2 - x1) / dt
vy = (y2 - y1) / dt
speed = math.sqrt(vx ** 2 + vy ** 2)
print("vx:", vx)
print("vy:", vy)
print("ball_velocity:", speed)
ball_posi.append(ball_position[0]) # ボール位置をball_posiに追加
if debug:
print("---------------------------------\n")
print("ball_position[0]: ", ball_position[0]) # デバッグ用に最新のボール位置を表示
print("---------------------------------\n")
print("ball_posi[0]: ", ball_posi[0]) # デバッグ用にひとつ前のボール位置を表示
print("---------------------------------\n")
if len(ball_posi) == 2: # 2つのボール位置がある場合
x1, y1, state1, frame1 = ball_posi[0] # ひとつ前のボール位置,状態,フレーム番号
x2, y2, state2, frame2 = ball_posi[1] # 最新のボール位置,状態,フレーム番号
dt = (frame2 - frame1) * (1/60) # フレーム間隔を秒に変換
vx = (x2 - x1) / dt # x方向の速度
vy = (y2 - y1) / dt # y方向の速度
speed = math.sqrt(vx ** 2 + vy ** 2) # ボールの速度
direction_rad = math.atan2(vy, vx) # 速度の方向をラジアンで計算
direction_deg = math.degrees(direction_rad) # 速度の方向を度に変換
if debug:
print("vx:", vx) # x方向の速度を表示
print("vy:", vy) # y方向の速度を表示
print("ball_velocity:", speed) # ボールの速度を表示
print("direction_deg:", direction_deg) # 速度の方向を表示
new_velocity_data = [[speed, direction_deg, state1, state2, frame2]] # 新しいボール速度のデータ
df = pd.DataFrame(new_velocity_data, columns=["speed", "direction", "state1", "state2", "frame_number"]) # ボール速度のデータフレームを作成
ball_velocity_path = os.path.join(path, "ball_velocity.csv") # ボール速度のCSVファイルパス
if not os.path.isdir(path):
os.mkdir(path) # 出力先ディレクトリが存在しない場合は作成
if not os.path.exists(ball_velocity_path):
df.to_csv(ball_velocity_path, mode='w', header=True, index=False) # ボール速度のCSVファイルが存在しない場合は新規作成
else:
df.to_csv(ball_velocity_path, mode='a', header=False, index=False) # 存在する場合は追記

ball_posi[0] = ball_posi[1] # 最新データを更新
ball_posi.pop(-1) # 2つを超えたら古いものを削除
except KeyboardInterrupt:
except KeyboardInterrupt: # キーボード割り込みで終了
break
40 changes: 20 additions & 20 deletions goal.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
import os
import pandas as pd

def goal_scene(track_ball_position, track_robot_position, path, stop_event, debug=False):
robot_poji_goal_path = os.path.join(path, "robot_position_goal.csv")
robot_position_path = os.path.join(path, "robot_position.csv")
poji_goal_x=6000
nega_goal_x=-6000
poji_goal_y=600
nega_goal_y=600
def goal_scene(track_ball_position, track_robot_position, path, stop_event, debug=False): # ゴールシーンの抽出
robot_poji_goal_path = os.path.join(path, "robot_position_goal.csv") # ロボットのポジションがゴールの時のCSVファイルパス
robot_position_path = os.path.join(path, "robot_position.csv") # ロボットのポジションのCSVファイルパス
poji_goal_x=6000 # 右側ゴールのX座標
nega_goal_x=-6000 # 左側ゴールのX座標
goal_top=900 # ゴールの上端
goal_bottom=-900 # ゴールの下端
if not os.path.isdir(path):
os.mkdir(path)
while not stop_event.is_set():
os.mkdir(path) # ディレクトリが存在しない場合は作成
while not stop_event.is_set(): # スレッドが停止されるまでループ
try:
balls_position = track_ball_position()
robot_poji = track_robot_position()
if balls_position and robot_poji:
ball_x, ball_y, state = balls_position[-1]
balls_position = track_ball_position() # ボールの位置を追跡
robot_poji = track_robot_position() # ロボットの位置を追跡
if balls_position and robot_poji:
ball_x, ball_y, state = balls_position[-1] # ボールの位置の最後の要素を取得
if ball_x > 6000:
if robot_poji and ((ball_x > poji_goal_x and (poji_goal_y > ball_y > nega_goal_y)) or (ball_x < nega_goal_x and (poji_goal_y > ball_y > nega_goal_y))):
df_robot_position = pd.read_csv(robot_position_path)
last_20_frames = df_robot_position.tail(120)
df = pd.DataFrame(last_20_frames)
df.to_csv(robot_poji_goal_path, header=True, index=False)
if robot_poji and ((ball_x > poji_goal_x and (goal_top > ball_y > goal_bottom)) or (ball_x < nega_goal_x and (goal_top > ball_y > goal_bottom))): # ゴールシーンの条件
df_robot_position = pd.read_csv(robot_position_path) # ロボットのポジションのCSVファイルを読み込み
last_20_frames = df_robot_position.tail(120) # 最後の120フレームを取得
df = pd.DataFrame(last_20_frames) # DataFrameを作成
df.to_csv(robot_poji_goal_path, header=True, index=False) # ゴールシーンのCSVファイルを保存
if debug:
print("ゴールシーンを保存しました")
except KeyboardInterrupt:
print("ゴールシーンを保存しました") # デバッグ用にゴールシーンを保存したことを表示
except KeyboardInterrupt: # キーボード割り込みが発生した場合
break
47 changes: 30 additions & 17 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,52 @@
from ball import store_ball_position,track_ball_position,ball_velocity
from robot import store_robot_position,track_robot_position
from goal import goal_scene
#プレフィックス省略のため from ファイル名 import メソッド名の形をとる。今後メソッドを追加した場合は追記すること。
import os

path = "out/"
stop_event = threading.Event()
debug = False
path = "out/" # 出力先ディレクトリ
stop_event = threading.Event() # スレッド停止用イベント
debug = False # デバッグ用フラグ

if __name__ == "__main__":
sock = setup_socket()
# main.py など
thread_ball = threading.Thread(
target=store_ball_position,
args=(udp, receive_packet, receive_game_controller_signal, stop_event, path, debug, sock)
sock = setup_socket() # ソケットのセットアップ
thread_ball = threading.Thread( # ボール位置のスレッド
target=store_ball_position, # ボール位置の保存
args=(udp, receive_packet, receive_game_controller_signal, stop_event, path, debug, sock) # ボール位置のスレッド引数
)
thread_ballvelocity = threading.Thread(target=ball_velocity, args=(udp, receive_packet,receive_game_controller_signal, stop_event, path, debug, sock))
# thread_robot = threading.Thread(target=store_robot_position, args=(udp, receive_packet, path, stop_event, debug))
# thread_goal = threading.Thread(target=goal_scene, args=(track_ball_position, track_robot_position, path, stop_event, debug))


thread_ballvelocity = threading.Thread( # ボール速度のスレッド
target=ball_velocity, # ボール速度の保存
args=(udp, receive_packet, receive_game_controller_signal, stop_event, path, debug, sock) # ボール速度のスレッド引数
)

# thread_robot = threading.Thread( # ロボット位置のスレッド
# target=store_robot_position, # ロボット位置の保存
# args=(udp, receive_packet, path, stop_event, debug) # ロボット位置のスレッド引数
# )

# thread_goal = threading.Thread( # ゴール位置のスレッド
# target=goal_scene, # ゴール位置の保存
# args=(track_ball_position, track_robot_position, path, stop_event, debug) # ゴール位置のスレッド引数
# )

# スレッドの開始
# thread_goal.start()
thread_ball.start()
# thread_robot.start()
thread_ballvelocity.start()

try:
thread_ball.join()
try: # スレッド終了を待機
thread_ball.join()
# thread_robot.join()
# thread_goal.join()
thread_ballvelocity.join()
except KeyboardInterrupt:
stop_event.set()
except KeyboardInterrupt: # キーボード割り込みで終了
stop_event.set() # スレッド停止イベントをセット
thread_ball.join()
# thread_robot.join()
# thread_goal.join()
thread_ballvelocity.join()
udp.close()
sock.close()
sock.close()
print("ソケットを閉じました")
68 changes: 34 additions & 34 deletions network.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,51 @@
import messages_robocup_ssl_wrapper_pb2
import ssl_gc_referee_message_pb2

local = "127.0.0.1"
multicast = "224.5.23.2"
port = 10006
buffer = 65536
addr = ('', port)
local = "127.0.0.1" # ローカルアドレスを指定
multicast = "224.5.23.2" # マルチキャストアドレスを指定
port = 10006 # ポート番号を指定
buffer = 65536 # バッファサイズを指定
addr = ('', port) # アドレスを指定

udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
udp.bind(addr)
udp.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(multicast) + socket.inet_aton(local))
udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDPソケットを作成
udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # アドレスの再利用を許可
udp.bind(addr) # ソケットをバインド
udp.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(multicast) + socket.inet_aton(local)) # マルチキャストグループに参加

def setup_socket():
global sock
buffer_size = 4096
multicast_group = '224.5.23.1'
server_address = ('', 10003)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(server_address)
group = socket.inet_aton(multicast_group)
mreq = struct.pack('4sL', group, socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
def setup_socket(): # ソケットのセットアップ
global sock # ソケットをグローバル変数として宣言
buffer_size = 4096 # バッファサイズを指定
multicast_group = '224.5.23.1' # マルチキャストグループを指定
server_address = ('', 10003) # サーバーアドレスを指定
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # ソケットを作成
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # アドレスの再利用を許可
sock.bind(server_address) # ソケットをバインド
group = socket.inet_aton(multicast_group) # マルチキャストグループを指定
mreq = struct.pack('4sL', group, socket.INADDR_ANY) # マルチキャストグループへの参加要求を作成
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) # マルチキャストグループに参加
return sock

def receive_packet(udp):
packet = messages_robocup_ssl_wrapper_pb2.SSL_WrapperPacket()
data, _ = udp.recvfrom(buffer)
packet.ParseFromString(data)
def receive_packet(udp): # パケットを受信
packet = messages_robocup_ssl_wrapper_pb2.SSL_WrapperPacket() # SSL_WrapperPacketを作成
data, _ = udp.recvfrom(buffer) # データを受信
packet.ParseFromString(data) # 受信したデータを解析,変換
return packet

def receive_game_controller_signal(sock, stop_event, buffer_size=4096, debug=False):
def receive_game_controller_signal(sock, stop_event, buffer_size=4096, debug=False): # ゲームコントローラーの信号を受信
try:
while not stop_event.is_set():
data, address = sock.recvfrom(buffer_size)
while not stop_event.is_set(): # 停止イベントがセットされるまでループ
data, address = sock.recvfrom(buffer_size) # データを受信
if debug:
print("データを受信しました from", address)
print("受信データ (バイナリ):", data)
print("データを受信しました from", address) # 受信元アドレスを表示
print("受信データ (バイナリ):", data) # 受信データ (バイナリ) を表示
try:
referee_message = ssl_gc_referee_message_pb2.Referee()
referee_message.ParseFromString(data)
referee_message = ssl_gc_referee_message_pb2.Referee() # Refereeメッセージを作成
referee_message.ParseFromString(data) # 受信したデータを解析
if debug:
print("Referee Message (人間が読みやすい形式):")
print("Referee Message (人間が読みやすい形式):") # 人間が読みやすい形式で表示
return referee_message.command
except Exception as e:
except Exception as e: # デコードエラー処理
print("RefereeMessage デコードエラー:", e)
print("----------------------")
except KeyboardInterrupt:
except KeyboardInterrupt: # キーボード割り込み処理
print("終了処理を開始します...")
Loading