Skip to content

Hands On Controller Binding

konodoki edited this page Jul 25, 2026 · 11 revisions

手把手 3:绑定按键并接入 Mod 路由

本课让键盘、手柄或 CRSF 都能触发 com.example.sin_wave/activate。状态侧只关心 btn_10=8

1. Mod 声明事件和 route

events:
  activate: {slot: btn_10, value: 8}

routes:
  - from: com.bxi.basic_actions/normal
    event: activate
    to: sin_wave
    transition: first_frame_switch

route 决定“收到事件后切到哪里”,Transition 决定“切换期间怎样输出电机帧”。这里不直接把 normal 的输出替换成正弦状态输出,是为了避免两边的关节目标和控制增益在一帧内跳变;first_frame_switch 会使用目标状态的进入帧逐步建立控制力。

2. 键盘 source

xbox_default.yaml 的 keyboard signals 增加:

keyboard.sin_wave: {from: keyboard.key, key: "0"}

3. control

controls:
  keyboard.sin_wave_event:
    type: bool
    inputs: [{source: keyboard.sin_wave}]

4. edge output

outputs:
  edge:
    - output: btn_10=8
      when:
        any:
          - [keyboard.sin_wave_event]

按键进入条件时只发一个脉冲。

5. 加入手柄

如果已有统一 control,例如 gamepad.a_event

    - output: btn_10=8
      when:
        any:
          - [keyboard.sin_wave_event]
          - [gamepad.a_event, gamepad.rb_event]

6. 加入 CRSF

使用已经解码的 enum control:

    - output: btn_10=8
      when:
        any:
          - [keyboard.sin_wave_event]
          - [crsf.button_group_a=y, crsf.rb_event]

具体 enum 区间和 failsafe 见 遥控器 YAML

7. 验证链路

物理键
  -> source
  -> bool/enum control
  -> edge output btn_10=8
  -> com.example.sin_wave/activate
  -> 当前 normal 状态的 route
  -> com.example.sin_wave/sin_wave
ros2 topic echo /motion_commands
ros2 topic echo /simulation/state_machine_info

常见问题

  • 消息有值但不切换:当前状态没有该 event 的 route。
  • 一按触发多次:应使用 edge,或检查按键 source 的 hold 设置。
  • 多事件冲突:同一状态下两个 event 可同时匹配同一槽位和值,Mod 加载会拒绝。
  • 修改遥控器 YAML 后无效:配置只在启动时读取;重新构建并重启 remote_controller

下一课:自定义过渡

Clone this wiki locally