import modes as mc import tkinter as tk from tkinter import ttk import threading import base_mode as bm IS_BOARD = True try: from pinpong.board import Board, Pin, NeoPixel from unihiker import GUI gui = GUI() except ModuleNotFoundError: print("警告:非行空板环境") IS_BOARD = False import time class XingkongBoardBase: def __init__(self): pass def on_btn_click(self, callback): """ 按下机外的那个按钮。 该按钮按键流程(必须辩论模式): 1. 进入立论模式(若是正方,则直接说话;若是反方,则直接开始录音) 2. 当本方为正方时,开始录(反方)音;为反方时,停止录(正方的)音 3. 当本方为正方时,停止录(反方)音;为反方时,开始说话 4. 当本方为正方时,进入进入自由辩论模式;为反方时,也是进入自由辩论模式(请确保灯光为绿) 5. 关闭自由辩论模式 6. 进入总结陈词模式。为正方时将直接开始录音;为反方时将直接输出语音,完成后辩论模式结束 7. 正方停止录音 8. 正方输出语音。完成后辩论模式结束 :param callback: 当按下时的回调函数 :return: """ pass def on_btn_dialog_click(self, callback): """ 按下“对话模式”按钮 :param callback: 当按下时的回调函数 :return: """ pass def on_btn_debate_click(self, callback): """ 按下“辩论模式”按钮 :param callback: 当按下时的回调函数 :return: """ pass def on_btn_stop_click(self, callback): """ 按下“停止”按钮 :param callback: 当按下时的回调函数 :return: """ pass def set_light_color(self, color): """ 设置灯光颜色。 在对话模式和自由辩论模式不设置灯光颜色。 red: 正在处理一些事件,此时不能点击机外按钮 green: 准备就绪,可以点击机外按钮 blue: 正在录音 orange: 成功进入辩论模式和自由辩论 :param color: "red"|"green"|"blue"|"orange" :return: """ pass SYSTEM = \ """ 你是人大附中经开学校金鹏科技团开发的辩论智能体机器人,名叫人开一号。 这个机器人运用了流式语音识别、大语言模型、流式语音合成等技术。 当你被要求介绍自己时,请简要介绍你的功能和技术实现。 请注意,你的回答将被直接通过语音合成输出,因此你不能输出不适合TTS的内容。 """ class Unihiker_Board(XingkongBoardBase): def __init__(self): super().__init__() Board().begin() # self.gui=GUI() self.btn21 = Pin(Pin.P21, Pin.IN) self.pin23 = Pin(Pin.D23) self.np1 = NeoPixel(self.pin23, 22) self.np1.brightness(150) gui.add_button(x=0, y=290, w=80, h=30, text="对话", origin='nw', onclick=self._trigger_dialog_click) gui.add_button(x=80, y=290, w=80, h=30, text="辩论", origin='nw', onclick=self._trigger_debate_click) gui.add_button(x=160, y=290, w=80, h=30, text="停止", origin='nw', onclick=self._trigger_stop_click) self.btn_count = 0 self.btn_callback = None self.dialog_callback = None self.debate_callback = None self.stop_callback = None def on_btn_click(self, callback): self.btn_callback = callback def on_btn_dialog_click(self, callback): self.dialog_callback = callback def on_btn_debate_click(self, callback): self.debate_callback = callback def on_btn_stop_click(self, callback): self.stop_callback = callback def set_light_color(self, color): if color == "red": self.np1.range_color(0, 21, 0xFF0000) if color == "green": self.np1.range_color(0, 21, 0x00FF00) if color == "blue": self.np1.range_color(0, 21, 0x0000FF) if color == "orange": self.np1.range_color(0, 21, 0xFFFF00) def _trigger_btn_click(self): if self.btn_callback: threading.Thread(target=self.btn_callback, daemon=True).start() def _trigger_dialog_click(self): if self.dialog_callback: threading.Thread(target=self.dialog_callback, daemon=True).start() def _trigger_debate_click(self): if self.debate_callback: threading.Thread(target=self.debate_callback, daemon=True).start() def _trigger_stop_click(self): if self.stop_callback: threading.Thread(target=self.stop_callback, daemon=True).start() def btn_click_check(self): while True: if self.btn21.read_digital() == 0: while self.btn21.read_digital() == 0: pass self._trigger_btn_click() def run(self): threading.Thread(target=self.btn_click_check, daemon=True).start() while True: time.sleep(1) class Robot: def __init__(self, board: XingkongBoardBase): self.modes = dict() self.btn_count = 0 self.board = board self.side = "" self.topic = "" self.opinion = "" self.last_prompt = "" self.session_id = None def register_mode(self, modename: str, mode: bm.Mode): self.modes[modename] = mode def run_mode(self, modename): self.modes[modename].run() def stop_mode(self, modename): self.modes[modename].stop() del self.modes[modename] def get_mode(self, modename): return self.modes[modename] def stop_all(self): for mode in self.modes.values(): mode.stop() self.modes.clear() def dialog(self): self.stop_all() self.board.set_light_color("orange") dialog_mode = mc.DialogMode(system_prompt=SYSTEM) self.register_mode("dialog", dialog_mode) self.run_mode("dialog") def set_debate_config(self, side, topic, opinion): self.side = side self.topic = topic self.opinion = opinion def debate(self): self.stop_all() self.board.set_light_color("orange") self.btn_count = 0 if self.side == "正方": self.board.on_btn_click(self._btn_right_callback) else: self.board.on_btn_click(self._btn_against_callback) def on_cancel(self): self.stop_all() self.board.set_light_color("green") def _btn_right_callback(self): self.btn_count += 1 if self.btn_count == 1: self.board.set_light_color("red") self.register_mode("make_point", mc.MakePointMode(side=self.side, topic=self.topic, opinion=self.opinion)) self.run_mode("make_point") self.board.set_light_color("green") elif self.btn_count == 2: md: mc.MakePointMode = self.get_mode("make_point") self.board.set_light_color("blue") md.start_record() elif self.btn_count == 3: md: mc.MakePointMode = self.get_mode("make_point") self.board.set_light_color("red") md.stop_record() self.board.set_light_color("green") self.last_prompt = md.ready_next() elif self.btn_count == 4: self.board.set_light_color("red") md: mc.MakePointMode = self.get_mode("make_point") self.session_id = md.session_id self.stop_mode("make_point") self.register_mode("free_debate", mc.FreeDebateMode(side=self.side, topic=self.topic, opinion=self.opinion, last_prompt=self.last_prompt, session_id=self.session_id)) self.run_mode("free_debate") self.board.set_light_color("orange") elif self.btn_count == 5: self.board.set_light_color("red") md: mc.FreeDebateMode = self.get_mode("free_debate") self.session_id = md.session_id self.stop_mode("free_debate") self.board.set_light_color("green") elif self.btn_count == 6: self.board.set_light_color("red") self.register_mode("end_debate", mc.EndDebateMode(side=self.side, topic=self.topic, opinion=self.opinion, session_id=self.session_id)) self.run_mode("end_debate") self.board.set_light_color("blue") elif self.btn_count == 7: md: mc.EndDebateMode = self.get_mode("end_debate") md.stop_record() self.board.set_light_color("green") elif self.btn_count == 8: self.board.set_light_color("red") md: mc.EndDebateMode = self.get_mode("end_debate") md.start_talk() self.board.set_light_color("green") self.stop_mode("end_debate") def _btn_against_callback(self): self.btn_count += 1 if self.btn_count == 1: self.board.set_light_color("blue") self.register_mode("make_point", mc.MakePointMode(side=self.side, topic=self.topic, opinion=self.opinion)) self.run_mode("make_point") elif self.btn_count == 2: md: mc.MakePointMode = self.get_mode("make_point") self.board.set_light_color("red") md.stop_record() self.board.set_light_color("green") elif self.btn_count == 3: self.board.set_light_color("red") md: mc.MakePointMode = self.get_mode("make_point") md.ready_next() self.board.set_light_color("green") elif self.btn_count == 4: self.board.set_light_color("red") md: mc.MakePointMode = self.get_mode("make_point") self.session_id = md.session_id self.stop_mode("make_point") self.register_mode("free_debate", mc.FreeDebateMode(side=self.side, topic=self.topic, opinion=self.opinion, session_id=self.session_id)) self.run_mode("free_debate") self.board.set_light_color("green") elif self.btn_count == 5: self.board.set_light_color("red") md: mc.FreeDebateMode = self.get_mode("free_debate") self.session_id = md.session_id self.stop_mode("free_debate") self.board.set_light_color("green") elif self.btn_count == 6: self.board.set_light_color("red") self.register_mode("end_debate", mc.EndDebateMode(side=self.side, topic=self.topic, opinion=self.opinion, session_id=self.session_id)) self.run_mode("end_debate") md: mc.EndDebateMode = self.get_mode("end_debate") md.start_talk() def run(self): self.board.on_btn_dialog_click(self.dialog) self.board.on_btn_debate_click(self.debate) self.board.on_btn_stop_click(self.on_cancel) class MockXingkongBoard(XingkongBoardBase): def __init__(self): super().__init__() self.root = tk.Tk() self.root.title("模拟控制台") self.root.geometry("300x200") # 灯光显示 self.light = tk.Label(self.root, width=10, height=5, bg="gray") self.light.pack(pady=10) # 按钮布局 btn_frame = ttk.Frame(self.root) btn_frame.pack(pady=10) # 机外按钮 ttk.Button(btn_frame, text="机外按钮", command=self._trigger_btn_click).grid(row=0, column=0, padx=5) # 功能按钮 ttk.Button(btn_frame, text="对话模式", command=self._trigger_dialog_click).grid(row=1, column=0, padx=5) ttk.Button(btn_frame, text="辩论模式", command=self._trigger_debate_click).grid(row=1, column=1, padx=5) ttk.Button(btn_frame, text="停止", command=self._trigger_stop_click).grid(row=1, column=2, padx=5) # 回调存储 self.btn_callback = None self.dialog_callback = None self.debate_callback = None self.stop_callback = None def on_btn_click(self, callback): self.btn_callback = callback def on_btn_dialog_click(self, callback): self.dialog_callback = callback def on_btn_debate_click(self, callback): self.debate_callback = callback def on_btn_stop_click(self, callback): self.stop_callback = callback def set_light_color(self, color): # 仅设置颜色,不添加任何模式判断 self.light.config(bg=color) def _trigger_btn_click(self): # 直接触发回调,高耗时操作放线程 if self.btn_callback: threading.Thread(target=self.btn_callback, daemon=True).start() def _trigger_dialog_click(self): if self.dialog_callback: threading.Thread(target=self.dialog_callback, daemon=True).start() def _trigger_debate_click(self): if self.debate_callback: threading.Thread(target=self.debate_callback, daemon=True).start() def _trigger_stop_click(self): if self.stop_callback: threading.Thread(target=self.stop_callback, daemon=True).start() def run(self): self.root.mainloop() if __name__ == '__main__': board = Unihiker_Board() if IS_BOARD else MockXingkongBoard() robot = Robot(board) robot.set_debate_config( "反方", "利用基因技术复活已灭绝物种(反灭绝工程)是生态责任还是资源浪费", "利用基因技术复活已灭绝物种(反灭绝工程)是资源浪费" ) if IS_BOARD else robot.set_debate_config( "反方", "量子计算机的实用化是否会首先对现有加密体系构成致命威胁", "量子计算机的实用化是否不会首先对现有加密体系构成致命威胁" ) robot.run() board.run()