Skip to content

Hands On Controller Binding

konodoki edited this page Aug 2, 2026 · 11 revisions

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

本课让键盘、手柄或 CRSF 都能触发 com.example.sin_wave/activate。状态 Mod 只依赖 btn_10=4,不需要知道输入来自哪一种设备。当前内置动作已占用 1/2/3/5/6/7/8/9/10, 因此示例使用空闲值 4;新增动作前仍应检查整棵 Mod 树是否占用了同一槽位和值。

1. Mod 声明事件和 route

events:
  activate:
    slot: btn_10
    value: 4

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

route 决定收到事件后切到哪里;Transition 决定切换期间怎样生成电机帧。 first_frame_switch 会读取目标状态的进入帧并逐步建立控制力,避免位置和增益在一帧内 突变。

2. 增加键盘 source

xbox_default.yaml 的 keyboard signals 中增加一个未占用键,例如 u

keyboard.sin_wave:
  from: keyboard.key
  key: "u"

不要复用当前已经绑定其他动作的数字键。

3. 增加键盘 control

controls:
  keyboard.sin_wave_event:
    type: bool
    inputs:
      - source: keyboard.sin_wave

4. 复用统一的手柄与 CRSF control

默认配置已经把两类设备合并成统一业务 control:

gamepad.trigger.left_event 或 crsf.trigger.left_event -> trigger.left_event
gamepad.b_event            或 crsf.b_event            -> button.b_event
gamepad/crsf shoulder event                             -> shoulder.*_event

因此 output 不应分别判断 gamepad.*crsf.*。统一组合只写一次,两种设备都会生效。

5. 补充 btn_10=4 输出

找到现有的 output: btn_10=4,把键盘分支加入同一个 binding。不要再创建第二个写入同一 字段和值的 binding:

outputs:
  level:
    - output: btn_10=4
      when:
        any:
          - - keyboard.sin_wave_event
          - - trigger.left_event
            - button.b_event
            - released: shoulder.left_event
            - released: shoulder.right_event
            - released: trigger.right_event

组合使用左扳机和 B;未参与组合的右扳机、左右肩键都必须显式为 released。否则按下三键 或四键时,较短组合也会同时满足,可能触发错误动作。

如果改用其他辅助键,规则相同:

按下的辅助键 + 面键 + 其余所有辅助键 released

四个辅助键是:

shoulder.left_event
shoulder.right_event
trigger.left_event
trigger.right_event

6. 验证链路

重新构建并启动 remote_controller 后检查:

ros2 topic echo /motion_commands
ros2 topic echo /simulation/state_machine_info

真机把 simulation 换成 hardware。预期链路是:

物理键
  -> source
  -> 统一 bool control
  -> level output btn_10=4
  -> com.example.sin_wave/activate
  -> 当前 normal 状态的 route
  -> com.example.sin_wave/sin_wave

至少验证以下组合:

  1. 只按左扳机和 B,可以触发。
  2. 同时多按右扳机,不触发该组合。
  3. 同时多按任一肩键,不触发该组合。
  4. 键盘 u 可以触发。
  5. 松开按键后 btn_10 回到 0

常见问题

  • 消息有值但不切换:当前状态没有该 event 的 route。
  • 完全没有输出:source、control 或 output 名称不一致。
  • 多键同时触发:缺少其他辅助键的 released 条件。
  • 输出冲突:同一字段由多个 binding 写入不同值;检查 conflict_policy 和 binding 顺序。
  • 修改后无效:重新构建并重启 remote_controller

下一课:自定义过渡

Clone this wiki locally