集成式人机交互与底层驱动系统设计说明书

模块名称: stm32_keyboard_control
核心节点: keyboard_control_node
固件对应: USER/main.c (STM32 Firmware)
适用阶段: 硬件调试 / SLAM 建图预备

1. 设计概述 (Design Overview)

在早期架构中,控制逻辑(Controller)与硬件接口(Driver)被物理分离。考虑到 STM32 固件采用了高效的字符流控制协议 ,我们将架构精简为集成式驱动模式 。本模块 keyboard_control_node 充当 ROS 2 上位机与底层硬件的唯一交互网关,通过多线程并发机制,同时实现毫秒级的人机交互控制与高频传感器数据采集。

1.1 系统上下文架构 (System Context Architecture)

2. 软件详细设计 (Software Detailed Design)

2.1 并发模型 (Concurrency Model)

为了保证控制的实时性与数据的完整性,节点内部采用异步多线程模型:

  1. 输入监听线程 (Daemon Thread):

    • 库 :pynput.keyboard
    • 职责:以非阻塞方式监听键盘中断事件(Press/Release)。
    • 同步机制 :通过原子变量或线程锁(Lock)更新全局控制状态 self.target_cmd。
    • 逻辑 :
      • on_press: 映射 WASD 为对应字符,置位 active_flag。
      • on_release: 触发死人开关 (Deadman Switch) 逻辑,立即发送停止指令或置位停止标志。
  2. IO 主线程 (Main Loop):

    • 库 :pyserial, rclpy.timer
    • 周期:20Hz (50ms)
    • 职责 (下行) :检查 self.target_cmd,向串口写入对应的 ASCII 字符(如 b'W')。
    • 职责 (上行) :读取串口缓冲区,以 \n 为定界符提取传感器数据帧。

2.2 通信协议规范 (Protocol Specification)

本系统采用非对称混合协议:下行控制追求极简低延迟,上行数据追求可读性与解析便利。

2.2.1 下行控制协议 (Host -> MCU)

类型: 单字节字符指令 (Single-Byte Character Command)
波特率: 115200 bps

动作 键位 发送载荷 (Hex) 固件响应函数 (main.c) 运动学描述
前进 W 0x57 SmoothControlSpeed(v, v, v, v) vx>0,ωz=0v_x > 0, \omega_z = 0vx>0,ωz=0
后退 S 0x53 SmoothControlSpeed(-v, -v, -v, -v) vx<0,ωz=0v_x < 0, \omega_z = 0vx<0,ωz=0
左转 A 0x41 SmoothControlSpeed(-v, -v, v, v) vx=0,ωz>0v_x = 0, \omega_z > 0vx=0,ωz>0 (原地左旋)
右转 D 0x44 SmoothControlSpeed(v, v, -v, -v) vx=0,ωz<0v_x = 0, \omega_z < 0vx=0,ωz<0 (原地右旋)
急停 Space 0x20 SmoothControlSpeed(0, 0, 0, 0) 强制阻尼制动
  • 心跳保活 :STM32 端的 CheckCommandTimeout 设定了 500ms 超时。上位机必须以至少 2Hz 的频率发送指令,否则机器人将自动停车。
2.2.2 上行反馈协议 (MCU -> Host)

类型: ASCII CSV 文本流
帧结束符: \n (0x0A)

  1. 里程计数据帧

    • 格式 :/four_wheel_encoder,<enc1>,<enc2>,<enc3>,<enc4>,<timestamp>

    • 解析示例 :

      python 复制代码
      # 原始数据: b'/four_wheel_encoder,102,-98,105,-100,12054\n'
      parts = line.decode().strip().split(',')
      if parts[0] == '/four_wheel_encoder':
          fl, fr, rl, rr = map(int, parts[1:5])
          ts = int(parts[5])
    • 物理意义 :encX 代表自上一次采样以来(约 20ms)各个轮子的脉冲增量 (Delta Pulse)。

  2. IMU 数据帧

    • 格式 :/imu_data,<ax>,<ay>,<az>,<gx>,<gy>,<gz>,<temp>,<timestamp>
    • 物理意义 :MPU6050 的原始 16 位寄存器值 (LSB)。需在上位机根据量程(如 ±2g, ±2000°/s)转换为标准单位 (m/s2m/s^2m/s2, rad/srad/srad/s)。

3. 关键算法实现 (Critical Implementation)

3.1 里程计解算 (Odometry Calculation)

为了支持 SLAM,keyboard_control_node 必须实现运动学正解 ,将编码器脉冲转换为机器人的位姿 (x,y,θ)(x, y, \theta)(x,y,θ)。

  • 参数定义 :
    • PULSE_PER_METER: ≈1571.0\approx 1571.0≈1571.0 (基于轮径 0.067m, 11线霍尔, 30:1 减速比)
    • WHEEL_TRACK: 0.17m0.17m0.17m (轮距)
  • 计算逻辑 (差速模型):
    1. 计算左右轮平均位移:
      ΔdL=enc1+enc32⋅Kscale,ΔdR=enc2+enc42⋅Kscale\Delta d_L = \frac{enc_1 + enc_3}{2} \cdot K_{scale}, \quad \Delta d_R = \frac{enc_2 + enc_4}{2} \cdot K_{scale}ΔdL=2enc1+enc3⋅Kscale,ΔdR=2enc2+enc4⋅Kscale
    2. 计算中心位移与旋转:
      Δs=ΔdR+ΔdL2,Δθ=ΔdR−ΔdLWtrack\Delta s = \frac{\Delta d_R + \Delta d_L}{2}, \quad \Delta \theta = \frac{\Delta d_R - \Delta d_L}{W_{track}}Δs=2ΔdR+ΔdL,Δθ=WtrackΔdR−ΔdL
    3. 更新全局位姿:
      xt=xt−1+Δs⋅cos⁡(θt−1+Δθ2)x_t = x_{t-1} + \Delta s \cdot \cos(\theta_{t-1} + \frac{\Delta \theta}{2})xt=xt−1+Δs⋅cos(θt−1+2Δθ)
      yt=yt−1+Δs⋅sin⁡(θt−1+Δθ2)y_t = y_{t-1} + \Delta s \cdot \sin(\theta_{t-1} + \frac{\Delta \theta}{2})yt=yt−1+Δs⋅sin(θt−1+2Δθ)
      θt=θt−1+Δθ\theta_t = \theta_{t-1} + \Delta \thetaθt=θt−1+Δθ

3.2 数据发布规范 (ROS 2 Interface)

解析后的数据需封装为以下标准消息:

  1. 里程计 (/odom)

    • 类型:nav_msgs/msg/Odometry
    • 坐标系:frame_id="odom", child_frame_id="base_link"
    • 内容:包含位姿 pose 和 速度 twist。
  2. TF 变换 (tf2_ros)

    • 必须 广播 odom -> base_link 的动态变换。这是 SLAM 算法(如 Cartographer 或 Slam Toolbox)定位机器人的基础。
    • 实现 :使用 tf2_ros.TransformBroadcaster。

4. 调试与集成指南 (Integration Guide)

4.1 启动步骤

  1. 授予串口权限 :

    bash 复制代码
    sudo chmod 777 /dev/ttyUSB0
  2. 运行节点 :

    bash 复制代码
    ros2 run stm32_keyboard_control keyboard_control_node
  3. 验证数据 :

    • 新开终端,检查是否收到 TF 数据:

      bash 复制代码
      ros2 run tf2_ros tf2_echo odom base_link
    • 如果只能控制但没有 TF 输出,说明上行数据解析逻辑缺失,需立即补全,否则 SLAM 无法运行。

4.2 常见问题排查

  • 现象 :机器人移动断断续续。
    • 原因:心跳发送频率低于 2Hz,触发了 STM32 的超时保护。
    • 对策 :检查 timer 回调频率,建议设为 10Hz 或 20Hz。
  • 现象 :TF 树断裂。
    • 原因 :未正确发布 /odom 话题或 TransformBroadcaster 未实例化。
    • 对策 :确保 keyboard_control_node 中包含里程计解算代码。
相关推荐
机器人零零壹41 分钟前
技术白皮书:iRobotCAM如何解决机器人激光切割应用中的核心难点,从CAD离线编程到双目视觉定位与轨迹自适应提升复杂空间曲线切割的精度、效率与柔性化水平
人工智能·算法
电子元件小说家2 小时前
2026年四季度电感市场观察:AI算力与汽车电子驱动下的选型与验证建议智能硬件
人工智能·汽车
网易CodeWave-小码哥2 小时前
支持多模块 Java 微服务导入|CodeWave SDD V4.5.10 上线
人工智能
AI你一生一世2 小时前
不止于时序存储:DolphinDB 如何成为 AI 时代的工业智能底座
java·人工智能·struts·时序数据库·工业智能·dolphindb·ai基础设施
belldeep2 小时前
python:genesis-world, Genesis-Embodied-AI
人工智能·python·ai·genesis
怕浪猫2 小时前
小程序成长计划上新:10 亿 Token 现在能调 DeepSeek-v4.1-flash了
人工智能·aigc·ai编程
ss2732 小时前
为什么PostgreSQL适合AI场景?
数据库·人工智能·postgresql
七牛云行业应用3 小时前
DeepSeek Super-agent 与 Grok Bot:开源 Agent 架构和聊天助手有何区别
人工智能·ai·架构·ai编程
ZhengEnCi3 小时前
大模型的分类到底怎么分:从基础模型到推理模型、从通用到专用的完整图谱
算法
维克兜率天3 小时前
【维克】趋势型CTA:期货市场的“追涨杀跌“
人工智能·python