diff --git a/judge/README.md b/judge/README.md index 550d025f..bfe83c0b 100644 --- a/judge/README.md +++ b/judge/README.md @@ -10,6 +10,19 @@ bash test_scripts/view_test.sh ``` 画面が出てうごけばOK +### 試合時間の設定 +`judgeServer.py`の引数で試合時間と延長時間を設定する。 + +--matchtime (--mt) 試合時間を秒単位で指定 + +--extendtime (--et) 引き分けだった場合の最大延長時間を秒単位で指定 + + +試合時間3分(180秒) 延長時間1分(60秒)の場合次のようになる。 +``` +python judgeServer.py --mt 180 --et 60 +``` + ### 試合の初期化スクリプト #### 引数 - マーカーセットのcsvファイル @@ -47,10 +60,10 @@ bash test_scripts/init_single_play.sh {makerset file} {server IP(default localho サンプル ``` -BL_B,5,0011 +BL_B,100,0011 BL_L,5,0012 BL_R,5,0013 -RE_B,5,0021 +RE_B,100,0021 RE_L,5,0022 RE_R,5,0023 hoge1_N,1,0064 diff --git a/judge/judgeServer.py b/judge/judgeServer.py index 5c921240..c0812964 100644 --- a/judge/judgeServer.py +++ b/judge/judgeServer.py @@ -28,13 +28,20 @@ def makeJson(self): class WarState: - def __init__(self): + def __init__(self, matchtime, extendtime=60.): self.state = "end" self.players = {"r": "NoPlayer", "b": "NoPlayer"} self.ready = {"r": False, "b": False} self.scores = {"r": 0, "b": 0} self.targets = [] + self.passed_time = 0. + self.init_time = None + self.stoped_time = 0. + + self.match_time = matchtime # [sec] + self.extend_time = extendtime # 1 minutes [sec] + def makeJson(self): json = { "players": self.players, @@ -42,9 +49,60 @@ def makeJson(self): "scores": self.scores, "state": self.state, "targets": [t.makeJson() for t in self.targets], + "time": self.passed_time, } return json + def makeCsv(self): + ''' + convert war_state to one line string + datetime, player_name_r, player_name_b, score_r, score_b, state, time, targets + ''' + csv_list = ["{0:%y%m%d-%H%M%S}".format(datetime.datetime.now()), + str(self.players["r"]), + str(self.players["b"]), + str(self.scores["r"]), + str(self.scores["b"]), + str(self.state), + str(self.stoped_time), + ' '.join([str(t.makeJson()) for t in self.targets]), + ] + csv = ','.join(csv_list) + return csv + + def updateTime(self): + app.logger.info("updateTime") + if self.init_time is None: + return False + + passed_time = self.stoped_time + (time.time() - self.init_time) + app.logger.info("passed_Time {}".format(passed_time)) + + if self.isOverMatchTime(passed_time): + self.setStateStop() + return True + else: + self.passed_time = passed_time + return False + + def isOverMatchTime(self, passed_time): + if passed_time > self.match_time + self.extend_time: + return True + elif passed_time > self.match_time: + if self.scores['r'] == self.scores['b']: + return False + else: + return True + else: + return False + + def setStateStop(self): + self.state = "stop" + self.init_time = None + self.stoped_time = self.passed_time + self.passed_time = 0. + + class Response: def __init__(self): self.mutch = False @@ -66,10 +124,15 @@ def makeJson(self): return json - class Referee: - def __init__(self): - self.war_state = WarState() + def __init__(self, matchtime, extendtime): + self.war_state = WarState(matchtime, extendtime) + + def getWarStateJson(self): + is_finished = self.war_state.updateTime() + if is_finished: + self.writeResult() + return self.war_state.makeJson() def judgeTargetId(self, player_name, player_side, target_id): ''' @@ -78,6 +141,12 @@ def judgeTargetId(self, player_name, player_side, target_id): ''' # make Response object response = Response() + + # Update time and check match time + is_finished = self.war_state.updateTime() + if is_finished: + self.writeResult() + # check id length if not len(target_id) == 4: app.logger.error("ERROR target length is not 4") @@ -106,14 +175,23 @@ def judgeTargetId(self, player_name, player_side, target_id): response.new = is_new response.error = "no error" response.target = target + + if self.isIPPONTarget(): + self.war_state.setStateStop() + self.writeResult() return response.makeJson() response.error = "ERR not mutch id" return response.makeJson() + + def isIPPONTarget(self): + return self.war_state.scores['r'] >= 100 or self.war_state.scores['b'] >= 100 + def checkBothPlayerReady(self): if self.war_state.ready["r"] and self.war_state.ready["b"]: - self.war_state.state = "running" - return + return True + else: + return False def updateWarState(self, target, player_name, player_side): # new target or not @@ -159,21 +237,36 @@ def registTarget(self, name, target_id, point): return target.name def setState(self, state): + app.logger.info("setState") if state == "end": self.war_state.state = state elif state == "running": if self.checkBothPlayerReady(): self.war_state.state = state + self.war_state.init_time = time.time() elif state == "stop": - self.war_state.state = state + self.war_state.setStateStop else: pass return state + def writeResult(self): + result_string = self.war_state.makeCsv() + script_dir = os.path.dirname(os.path.abspath(__file__)) + log_file_path = script_dir + "/log/" + "game_result.log" + with open(log_file_path, "a") as f: + f.write(result_string + "\n") + app.logger.info("Write Result {}".format(result_string)) -# global object referee -referee = Referee() +import argparse +parser = argparse.ArgumentParser(description='burger_war judger server') +parser.add_argument('--matchtime', '--mt', default=float('inf'), type=float, help='match time [sec]') +parser.add_argument('--extendtime','--et', default=60, type=float, help='extend time [sec]') +args = parser.parse_args() + +# global object referee +referee = Referee(args.matchtime, args.extendtime) @app.route('/') def index(): @@ -202,7 +295,7 @@ def judgeTargetId(): def getState(): ip = request.remote_addr #app.logger.info("GET /warState " + str(ip)) - state_json = referee.war_state.makeJson() + state_json = referee.getWarStateJson() res = state_json #app.logger.info("RESPONSE /warState "+ str(ip) + str(res)) return jsonify(res) @@ -266,18 +359,6 @@ def getTest(): return jsonify(res) -@app.route('/test', methods=['POST']) -def postTest(): - body = request.json - ip = request.remote_addr - app.logger.info(str(ip) + body ) - state = body["state"] - ret = referee.setState(state) - res = ret - app.logger.info("RESPONSE /test "+ str(ip) + str(res)) - return jsonify(res) - - if __name__ == '__main__': now = datetime.datetime.now() now_str = now.strftime("%y%m%d_%H%M%S") diff --git a/judge/marker_set/marker_set_default.csv b/judge/marker_set/marker_set_default.csv index dbcf7902..e99a797f 100644 --- a/judge/marker_set/marker_set_default.csv +++ b/judge/marker_set/marker_set_default.csv @@ -1,7 +1,7 @@ -BL_B,5,0011 +BL_B,100,0011 BL_L,5,0012 BL_R,5,0013 -RE_B,5,0021 +RE_B,100,0021 RE_L,5,0022 RE_R,5,0023 Tomato_N,1,0064 diff --git a/judge/marker_set/sim.csv b/judge/marker_set/sim.csv index 39150c44..7e0af418 100644 --- a/judge/marker_set/sim.csv +++ b/judge/marker_set/sim.csv @@ -1,7 +1,7 @@ -BL_B,5,0052 +BL_B,100,0052 BL_L,5,0050 BL_R,5,0051 -RE_B,5,0042 +RE_B,100,0042 RE_L,5,0040 RE_R,5,0041 Tomato_N,1,0009 diff --git a/judge/visualizeWindow.py b/judge/visualizeWindow.py index c7944f14..e8a3b5c3 100644 --- a/judge/visualizeWindow.py +++ b/judge/visualizeWindow.py @@ -230,25 +230,31 @@ def update(self, _display): # print(state_json) j = json.dumps(state_json) state = json.loads(state_json) - + #Get background image display = copy.deepcopy(_display) #試合開始時間の初期化 if(self.init_time is None and state["state"] == "running"): self.init_time = datetime.datetime.now() - + ##### #文字の表示 cv2.putText(display, "Game State: " + state["state"], (self.w_width*1/4, self.w_height/20), self.font, self.font_size, self.text_color, self.text_thickness) s = cv2.getTextSize("Game State: " + state["state"], self.font, self.font_size, self.text_thickness) cv2.putText(display, "Players", (self.w_width*3/7, self.w_height*1/7-10), self.font, self.font_size, self.text_color, self.text_thickness) cv2.putText(display, " Score ", (self.w_width*3/7, self.w_height*2/7-70), self.font, self.font_size, self.text_color, self.text_thickness) + #経過時刻の表示 + ''' if(self.init_time is not None): elapsed_datetime = datetime.datetime.now() - self.init_time # print(elapsed_datetime) - cv2.putText(display, str(elapsed_datetime)[:-5], (self.w_width*3/7, self.w_height*2/7+10), self.font, self.font_size, self.text_color, self.text_thickness) + #cv2.putText(display, str(elapsed_datetime)[:-5], (self.w_width*3/7, self.w_height*2/7+10), self.font, self.font_size, self.text_color, self.text_thickness) + ''' + + elapsed_datetime = state["time"] + cv2.putText(display, str(elapsed_datetime)[:-5], (self.w_width*3/7, self.w_height*2/7+10), self.font, self.font_size, self.text_color, self.text_thickness) #スコア表示 for player, position in ("b", 0), ("r", self.w_width*12/20): @@ -258,7 +264,7 @@ def update(self, _display): ready_color = (200,200,200) cv2.putText(display, state["players"][player].center(10, ' '), (position, self.w_height*1/7),self.font, self.font_size+2, ready_color, self.text_thickness) cv2.putText(display, str(state["scores"][player]).center(10, ' '), (position, self.w_height*2/7-50), self.font, self.font_size+2, ready_color, self.text_thickness) - + if len(state["targets"])>0: for target in state["targets"]: if(target["player"]=="n"): @@ -285,14 +291,14 @@ def update(self, _display): self.last_score_time[target["player"]] = str(elapsed_time)[:-5] self.histories.append(target["name"]) - cv2.putText(display, "Last Score Time:", (1000, 750), self.font, 2, self.p_color["r"], 2) - cv2.putText(display, self.last_score_time["r"], (1000, 800), self.font, 4, self.p_color["r"], 3) - cv2.putText(display, "Last Score Time:", (50, 500), self.font, 2, self.p_color["b"], 2) - cv2.putText(display, self.last_score_time["b"], (50, 550), self.font, 4, self.p_color["b"], 3) - - + #cv2.putText(display, "Last Score Time:", (1000, 750), self.font, 2, self.p_color["r"], 2) + #cv2.putText(display, self.last_score_time["r"], (1000, 800), self.font, 4, self.p_color["r"], 3) + #cv2.putText(display, "Last Score Time:", (50, 500), self.font, 2, self.p_color["b"], 2) + #cv2.putText(display, self.last_score_time["b"], (50, 550), self.font, 4, self.p_color["b"], 3) + + ##### - + cv2.imshow(self.w_name, display) cv2.waitKey(3) @@ -301,7 +307,8 @@ def update(self, _display): sw = StatusWindow(w_name="Onigiri War") display = sw.initWindow() - + while(True): sw.update(display) sleep(1) + diff --git a/scripts/setup_semifinal.sh b/scripts/setup_semifinal.sh new file mode 100644 index 00000000..1797b84f --- /dev/null +++ b/scripts/setup_semifinal.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -e +set -x + +RED_NAME=$1 +BLUE_NAME=$2 + +# judge +# run judge server and visualize window +gnome-terminal -e "python judge/judgeServer.py --mt 180 --et 60" +gnome-terminal -e "python judge/visualizeWindow.py" + +# init judge server for sim setting +bash judge/test_scripts/init_single_play.sh judge/marker_set/sim.csv localhost:5000 $RED_NAME $BLUE_NAME + +# robot +roslaunch burger_war setup_sim.launch +