TeX capacity exceeded, sorry [save size=80000]. \xeCJKResetCharClass

运行环境为TeX Live 2016/W32Tex+TeXstudio

错误提示如下:
这里写图片描述

可能要注意的问题:
1.ctex和xeCJk冲突,注意两个宏包的顺序,更推荐只使用一个xeCJk宏包;
2.xeCJK或者ctex放在 \input{}载入其他宏包 之前,问题就解决了。
这里写图片描述
总结:遇到Latex问题还是多求助于texdoc帮助文档。

import time import pickle import numpy as np from mini_bdx_runtime.rustypot_position_hwi import HWI from mini_bdx_runtime.onnx_infer import OnnxInfer from mini_bdx_runtime.raw_imu import Imu from mini_bdx_runtime.poly_reference_motion import PolyReferenceMotion from mini_bdx_runtime.xbox_controller import XBoxController from mini_bdx_runtime.feet_contacts import FeetContacts from mini_bdx_runtime.eyes import Eyes from mini_bdx_runtime.sounds import Sounds from mini_bdx_runtime.antennas import Antennas from mini_bdx_runtime.projector import Projector from mini_bdx_runtime.rl_utils import make_action_dict, LowPassActionFilter from mini_bdx_runtime.duck_config import DuckConfig import os HOME_DIR = os.path.expanduser("~") class RLWalk: def __init__( self, onnx_model_path: str, duck_config_path: str = f"{HOME_DIR}/duck_config.json", serial_port: str = "/dev/ttyACM0", control_freq: float = 50, pid=[30, 0, 0], action_scale=0.25, commands=False, pitch_bias=0, save_obs=False, replay_obs=None, cutoff_frequency=None, ): self.duck_config = DuckConfig(config_json_path=duck_config_path) self.commands = commands self.pitch_bias = pitch_bias self.onnx_model_path = onnx_model_path self.policy = OnnxInfer(self.onnx_model_path, awd=True) self.num_dofs = 14 self.max_motor_velocity = 5.24 # rad/s # Control self.control_freq = control_freq self.pid = pid self.save_obs = save_obs if self.save_obs: self.saved_obs = [] self.replay_obs = replay_obs if self.replay_obs is not None: self.replay_obs = pickle.load(open(self.replay_obs, "rb")) self.action_filter = None if cutoff_frequency is not None: self.action_filter = LowPassActionFilter( self.control_freq, cutoff_frequency ) self.hwi = HWI(self.duck_config, serial_port) self.start() self.imu = Imu( sampling_freq=int(self.control_freq), user_pitch_bias=self.pitch_bias, upside_down=self.duck_config.imu_upside_down, ) self.feet_contacts = FeetContacts() # Scales self.action_scale = action_scale self.last_action = np.zeros(self.num_dofs) self.last_last_action = np.zeros(self.num_dofs) self.last_last_last_action = np.zeros(self.num_dofs) self.init_pos = list(self.hwi.init_pos.values()) self.motor_targets = np.array(self.init_pos.copy()) self.prev_motor_targets = np.array(self.init_pos.copy()) self.last_commands = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] self.paused = self.duck_config.start_paused self.command_freq = 20 # hz if self.commands: self.xbox_controller = XBoxController(self.command_freq) # Reference motion, but we only really need the length of one phase # TODO self.PRM = PolyReferenceMotion("./polynomial_coefficients.pkl") self.imitation_i = 0 self.imitation_phase = np.array([0, 0]) self.phase_frequency_factor = 1.0 self.phase_frequency_factor_offset = ( self.duck_config.phase_frequency_factor_offset ) # Optional expression features if self.duck_config.eyes: self.eyes = Eyes() if self.duck_config.projector: self.projector = Projector() if self.duck_config.speaker: self.sounds = Sounds( volume=1.0, sound_directory="../mini_bdx_runtime/assets/" ) if self.duck_config.antennas: self.antennas = Antennas() def get_obs(self): imu_data = self.imu.get_data() dof_pos = self.hwi.get_present_positions( ignore=[ "left_antenna", "right_antenna", ] ) # rad dof_vel = self.hwi.get_present_velocities( ignore=[ "left_antenna", "right_antenna", ] ) # rad/s if dof_pos is None or dof_vel is None: return None if len(dof_pos) != self.num_dofs: print(f"ERROR len(dof_pos) != {self.num_dofs}") return None if len(dof_vel) != self.num_dofs: print(f"ERROR len(dof_vel) != {self.num_dofs}") return None cmds = self.last_commands feet_contacts = self.feet_contacts.get() obs = np.concatenate( [ imu_data["gyro"], imu_data["accelero"], cmds, dof_pos - self.init_pos, dof_vel * 0.05, self.last_action, self.last_last_action, self.last_last_last_action, self.motor_targets, feet_contacts, self.imitation_phase, ] ) return obs def start(self): kps = [self.pid[0]] * 14 kds = [self.pid[2]] * 14 # lower head kps kps[5:9] = [8, 8, 8, 8] self.hwi.set_kps(kps) self.hwi.set_kds(kds) self.hwi.turn_on() time.sleep(2) def get_phase_frequency_factor(self, x_velocity): max_phase_frequency = 1.2 min_phase_frequency = 1.0 # Perform linear interpolation freq = min_phase_frequency + (abs(x_velocity) / 0.15) * ( max_phase_frequency - min_phase_frequency ) return freq def run(self): i = 0 try: print("Starting") start_t = time.time() while True: left_trigger = 0 right_trigger = 0 t = time.time() if self.commands: self.last_commands, self.buttons, left_trigger, right_trigger = ( self.xbox_controller.get_last_command() ) if self.buttons.dpad_up.triggered: self.phase_frequency_factor_offset += 0.05 print( f"Phase frequency factor offset {round(self.phase_frequency_factor_offset, 3)}" ) if self.buttons.dpad_down.triggered: self.phase_frequency_factor_offset -= 0.05 print( f"Phase frequency factor offset {round(self.phase_frequency_factor_offset, 3)}" ) if self.buttons.LB.is_pressed: self.phase_frequency_factor = 1.3 else: self.phase_frequency_factor = 1.0 if self.buttons.X.triggered: if self.duck_config.projector: self.projector.switch() if self.buttons.B.triggered: if self.duck_config.speaker: self.sounds.play_random_sound() if self.duck_config.antennas: self.antennas.set_position_left(right_trigger) self.antennas.set_position_right(left_trigger) if self.buttons.A.triggered: self.paused = not self.paused if self.paused: print("PAUSE") else: print("UNPAUSE") if self.paused: time.sleep(0.1) continue obs = self.get_obs() if obs is None: continue self.imitation_i += 1 * ( self.phase_frequency_factor + self.phase_frequency_factor_offset ) self.imitation_i = self.imitation_i % self.PRM.nb_steps_in_period self.imitation_phase = np.array( [ np.cos( self.imitation_i / self.PRM.nb_steps_in_period * 2 * np.pi ), np.sin( self.imitation_i / self.PRM.nb_steps_in_period * 2 * np.pi ), ] ) if self.save_obs: self.saved_obs.append(obs) if self.replay_obs is not None: if i < len(self.replay_obs): obs = self.replay_obs[i] else: print("BREAKING ") break action = self.policy.infer(obs) self.last_last_last_action = self.last_last_action.copy() self.last_last_action = self.last_action.copy() self.last_action = action.copy() # action = np.zeros(10) self.motor_targets = self.init_pos + action * self.action_scale # self.motor_targets = np.clip( # self.motor_targets, # self.prev_motor_targets # - self.max_motor_velocity * (1 / self.control_freq), # control dt # self.prev_motor_targets # + self.max_motor_velocity * (1 / self.control_freq), # control dt # ) if self.action_filter is not None: self.action_filter.push(self.motor_targets) filtered_motor_targets = self.action_filter.get_filtered_action() if ( time.time() - start_t > 1 ): # give time to the filter to stabilize self.motor_targets = filtered_motor_targets self.prev_motor_targets = self.motor_targets.copy() head_motor_targets = self.last_commands[3:] + self.motor_targets[5:9] self.motor_targets[5:9] = head_motor_targets action_dict = make_action_dict( self.motor_targets, list(self.hwi.joints.keys()) ) self.hwi.set_position_all(action_dict) i += 1 took = time.time() - t # print("Full loop took", took, "fps : ", np.around(1 / took, 2)) if (1 / self.control_freq - took) < 0: print( "Policy control budget exceeded by", np.around(took - 1 / self.control_freq, 3), ) time.sleep(max(0, 1 / self.control_freq - took)) except KeyboardInterrupt: if self.duck_config.antennas: self.antennas.stop() if self.save_obs: pickle.dump(self.saved_obs, open("robot_saved_obs.pkl", "wb")) print("TURNING OFF") if __name__ == "__main__": import argparse parser = argparse.ArgumentParser() parser.add_argument("--onnx_model_path", type=str, required=True) parser.add_argument( "--duck_config_path", type=str, required=False, default=f"{HOME_DIR}/duck_config.json", ) parser.add_argument("-a", "--action_scale", type=float, default=0.25) parser.add_argument("-p", type=int, default=30) parser.add_argument("-i", type=int, default=0) parser.add_argument("-d", type=int, default=0) parser.add_argument("-c", "--control_freq", type=int, default=50) parser.add_argument("--pitch_bias", type=float, default=0, help="deg") parser.add_argument( "--commands", action="store_true", default=True, help="external commands, keyboard or gamepad. Launch control_server.py on host computer", ) parser.add_argument( "--save_obs", type=str, required=False, default=False, help="save the run's observations", ) parser.add_argument( "--replay_obs", type=str, required=False, default=None, help="replay the observations from a previous run (can be from the robot or from mujoco)", ) parser.add_argument("--cutoff_frequency", type=float, default=None) args = parser.parse_args() pid = [args.p, args.i, args.d] print("Done parsing args") rl_walk = RLWalk( args.onnx_model_path, duck_config_path=args.duck_config_path, action_scale=args.action_scale, pid=pid, control_freq=args.control_freq, commands=args.commands, pitch_bias=args.pitch_bias, save_obs=args.save_obs, replay_obs=args.replay_obs, cutoff_frequency=args.cutoff_frequency, ) print("Done instantiating RLWalk") rl_walk.run() 这个程序为什么手柄按A有反应,按B X Y left right LB 都没反应?
最新发布
07-30
<think>我们正在处理一个关于Python程序中Xbox手柄按钮事件未触发的问题。用户提到B、X、Y、LB和左右方向键未触发事件。 首先,我们需要考虑可能的原因。在Python中,通常使用游戏手柄库如pygame或inputs来读取手柄输入。常见的问题包括: 1. 手柄连接问题:手柄是否已正确连接并被系统识别? 2. 库的兼容性问题:使用的库是否支持Xbox手柄?是否支持所有按钮? 3. 事件处理代码问题:代码中是否正确处理了这些按钮的事件? 4. 按钮映射问题:不同手柄的按钮映射可能不同,代码中是否使用了正确的按钮标识符? 根据用户的问题,我们重点分析按钮B、X、Y、LB和左右方向键(注意:左右方向键通常指D-pad的左右,而不是摇杆)。 由于用户没有提供代码,我们将给出一般性的排查步骤和示例代码。 步骤1:确认手柄连接 在系统设置中检查手柄是否被识别,并测试按钮在系统层面是否有效(例如在游戏控制器设置中测试)。 步骤2:检查使用的库和按钮映射 以pygame为例,pygame中按钮的标识符是预定义的常量,如`pygame.JOYBUTTONDOWN`事件中的`button`属性。不同按钮对应不同的数字。 常见的Xbox手柄在pygame中的映射(注意:映射可能因手柄型号和操作系统略有不同): - A按钮:0 - B按钮:1 - X按钮:2 - Y按钮:3 - LB:4 - RB:5 - Back:6 - Start:7 - 左摇杆按下:8 - 右摇杆按下:9 方向键(D-pad)在pygame中通常被当作hat(帽子开关)事件处理,事件类型为`pygame.JOYHATMOTION`。方向键的左右对应hat的x轴:左为-1,右为1,上为1,下为-1(注意:hat事件返回的是一个元组(hat_x, hat_y))。 步骤3:确保事件循环中处理了所有事件 在pygame中,需要轮询事件并处理`JOYBUTTONDOWN`、`JOYHATMOTION`等事件。 示例代码: 以下是一个简单的pygame手柄事件监听示例,包括按钮和hat(方向键)事件。 ```python import pygame pygame.init() # 初始化手柄 pygame.joystick.init() joystick_count = pygame.joystick.get_count() if joystick_count == 0: print("未检测到手柄") exit() # 获取第一个手柄 joystick = pygame.joystick.Joystick(0) joystick.init() print(f"手柄名称: {joystick.get_name()}") # 事件循环 running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 处理按钮按下事件 if event.type == pygame.JOYBUTTONDOWN: print(f"按钮 {event.button} 按下") # 处理方向键(hat)事件 if event.type == pygame.JOYHATMOTION: # event.hat 表示哪个hat(通常0是主方向键),event.value 是(x, y)值 print(f"Hat {event.hat} 移动: {event.value}") # 也可以处理摇杆事件(如果需要) if event.type == pygame.JOYAXISMOTION: # event.axis 是轴编号,event.value 是当前值(-1.0到1.0) # 通常左摇杆:轴0(左右)、轴1(上下);右摇杆:轴2(左右)、轴3(上下) pass pygame.quit() ``` 步骤4:调试 运行上述代码,按下有问题的按钮(B、X、Y、LB)和方向键(左右),查看控制台输出。 对于方向键,注意输出的是`JOYHATMOTION`事件。如果方向键没有触发事件,检查hat的编号(通常为0)和返回值。左右方向键应返回(-1,0)和(1,0)(假设y轴为0)。 对于LB按钮,它应该触发`JOYBUTTONDOWN`事件,按钮编号为4。 如果这些按钮没有输出,可能是手柄映射问题。可以尝试打印所有事件来检查。 步骤5:使用其他库验证 如果pygame无法检测到,可以尝试使用其他库如`inputs`。安装:`pip install inputs` 使用inputs的示例: ```python from inputs import get_gamepad while True: events = get_gamepad() for event in events: print(event.ev_type, event.code, event.state) ``` 运行后按按钮,查看输出。例如,按下B按钮可能输出类似`Key`或`Button`事件,code为`BTN_SOUTH`(但具体取决于系统)。 步骤6:其他可能原因 - 多个手柄库冲突:确保没有同时使用多个库(如pygame和inputs)导致资源占用。 - 权限问题(Linux):可能需要将用户加入input组。 - 驱动程序问题(Windows):确保Xbox手柄驱动正常。 根据以上步骤,用户应能定位问题所在。 生成相关问题: 1. 如何获取pygame中手柄按钮的完整映射表? 2. 在Linux系统中,Python程序无法检测到手柄事件怎么办? 3. 如何使用inputs库读取Xbox手柄的摇杆和按钮事件? 4. 如何解决多个程序同时访问手柄导致的输入冲突?</think>### Xbox手柄按钮事件未触发问题分析 在Python中调试Xbox手柄按钮事件未触发的问题,可能涉及以下原因及排查步骤: #### 1. **手柄映射问题** Xbox手柄的按钮在不同库中有不同的标识符映射: - **Pygame映射**: ```python BUTTON_A = 0 BUTTON_B = 1 # 未触发按钮 BUTTON_X = 2 # 未触发按钮 BUTTON_Y = 3 # 未触发按钮 BUTTON_LB = 4 # 未触发按钮 HAT_LEFT = (-1, 0) # 方向键左 HAT_RIGHT = (1, 0) # 方向键右 ``` - **问题原因**:代码可能使用了错误的按钮索引或未正确处理方向键的`JOYHATMOTION`事件。 - **验证方法**:打印所有按钮事件,确认映射关系: ```python for event in pygame.event.get(): if event.type == pygame.JOYBUTTONDOWN: print(f"按钮 {event.button} 按下") # 检查B/X/Y/LB对应的索引 elif event.type == pygame.JOYHATMOTION: print(f"方向键状态: {event.value}") # 检查左右方向值 ``` #### 2. **事件捕获缺失** - 方向键(D-pad)在Pygame中属于**帽子开关(Hat)事件**,而非普通按钮事件: ```python # 错误方式:方向键不会触发JOYBUTTONDOWN # 正确方式:必须监听JOYHATMOTION if event.type == pygame.JOYHATMOTION: if event.value == (1, 0): # 右方向键 print("右方向键按下") elif event.value == (-1, 0): # 左方向键 print("左方向键按下") ``` - **LB按钮**:确保未与其他触发器混淆(如`pygame.JOYAXISMOTION`中的轴5)。 #### 3. **手柄初始化问题** - 未正确初始化手柄或未启用事件捕获: ```python pygame.joystick.init() if pygame.joystick.get_count() > 0: joystick = pygame.joystick.Joystick(0) joystick.init() # 必须初始化 ``` - **驱动问题**:在设备管理器中检查手柄是否被识别为"Xbox Controller"。 #### 4. **硬件/连接问题** - 使用系统工具(如Windows的"游戏控制器设置")测试按钮是否物理可用。 - 尝试更换USB接口或重启手柄(长按Xbox按钮10秒重置)。 #### 5. **库版本兼容性** - 更新Pygame库: ```bash pip install --upgrade pygame ``` - 若使用其他库(如`inputs`),检查Xbox按钮命名: ```python from inputs import get_gamepad for event in get_gamepad(): if event.code == "BTN_SOUTH": # B按钮 print("B按钮按下") elif event.code == "ABS_HAT0X": # 方向键水平轴 print(f"方向键: {event.state}") ``` #### 调试建议 1. **完整事件监听代码示例**: ```python import pygame pygame.init() pygame.joystick.init() joystick = pygame.joystick.Joystick(0) joystick.init() while True: for event in pygame.event.get(): if event.type == pygame.JOYBUTTONDOWN: print(f"按钮 {event.button} 按下") elif event.type == pygame.JOYHATMOTION: print(f"方向键: {event.value}") elif event.type == pygame.JOYAXISMOTION: if event.axis == 5: # LB触发器(轴5) print(f"LB触发值: {event.value}") ``` 2. **使用第三方工具验证**: - 下载[Joystick Tester](https://gamepad-tester.com/)在线测试按钮响应。 - 使用`pygame.joystick.Joystick.get_numbuttons()`确认手柄支持的按钮数量。 > 若问题仍存在,可能是手柄固件问题或Python库的特定兼容性Bug,建议尝试更换库(如`inputs`)或使用C++/C#验证硬件功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tingzhushaohua

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值