跳到主要内容

Robot PU 状态机

🤖 Robot PU 教程:使用状态机构建舞蹈程序

MakeCode + Robot PU 的 JavaScript 教程


机器人擅长重复模式,但如果你只使用 basic.forever() 编写舞蹈程序,很快就会陷入定时器、暂停和嵌套条件的混乱之中。

状态机为你提供了一种干净、可预测的方式来组织复杂的机器人行为——尤其是像跳舞这样的序列。

本教程将向你展示如何:

  • 理解什么是状态机
  • 在 MakeCode 中构建一个简单的状态机
  • 使用事件和定时器在状态之间转换
  • 实现一个完整的 Robot PU 舞蹈程序

🎯 什么是状态机?

状态机是一种设计模式,机器人始终处于且仅处于一个状态,例如:

  • IDLE(空闲)
  • STEP_LEFT(左踏步)
  • STEP_RIGHT(右踏步)
  • SPIN(旋转)
  • POSE(摆姿势)

每个状态定义了:

  • 机器人做什么
  • 何时以及如何转换到下一个状态

可以把它想象成编舞: "做动作 A 持续 1 秒 → 然后做动作 B 持续 1 秒 → 然后做动作 C……"


🧱 1. 定义状态

我们将使用数字或字符串来定义状态。 数字更快,但字符串更易读。

enum DanceState {
Idle,
StepLeft,
StepRight,
Spin,
Pose
}

let state = DanceState.Idle

🕹️ 2. 状态机循环

我们使用 forever() 循环来运行当前状态。

basic.forever(function () {
switch (state) {

case DanceState.Idle:
robotPu.walk(0, 0)
break

case DanceState.StepLeft:
robotPu.walk(1.2, -1)
break

case DanceState.StepRight:
robotPu.walk(1.2, 1)
break

case DanceState.Spin:
robotPu.walk(1.5, 1)
break

case DanceState.Pose:
robotPu.walk(0, 0)
basic.showIcon(IconNames.Heart)
break
}

basic.pause(20)
})

这个循环不决定何时改变状态——它只执行当前状态的动作。

状态转换在下一步处理。


⏱️ 3. 定时状态转换

我们将使用 control.setTimeout() 来安排转换。

辅助函数:

function nextState(s: DanceState, delay: number) {
control.setTimeout(() => {
state = s
}, delay)
}

这让我们可以像这样编写编舞:

左踏步 800ms → 右踏步 800ms → 旋转 1200ms → 摆姿势


💃 4. 启动舞蹈程序

让我们通过按下按钮 A 来触发舞蹈。

input.onButtonPressed(Button.A, function () {
startDance()
})

舞蹈序列:

function startDance() {

// Start with left step
state = DanceState.StepLeft
nextState(DanceState.StepRight, 800)

// Then right step
nextState(DanceState.Spin, 1600)

// Then spin
nextState(DanceState.Pose, 2800)

// End in pose
nextState(DanceState.Idle, 4000)
}

注意每个 nextState() 调用在时间上是偏移的。 这就创建了一条动作的时间线。


🧠 5. 为什么这样做如此有效

  • 清晰的分离 — 状态机循环处理运动;转换调度器处理时序
  • 易于扩展 — 通过添加新状态来增加新动作
  • 易于调试 — 你始终知道机器人当前处于哪个状态
  • 没有复杂的暂停control.setTimeout() 避免阻塞主循环

🕺 6. 完整舞蹈程序代码(完整示例)

enum DanceState {
Idle,
StepLeft,
StepRight,
Spin,
Pose
}

let state = DanceState.Idle

// State machine loop
basic.forever(function () {
switch (state) {

case DanceState.Idle:
robotPu.walk(0, 0)
break

case DanceState.StepLeft:
robotPu.walk(1.2, -1)
break

case DanceState.StepRight:
robotPu.walk(1.2, 1)
break

case DanceState.Spin:
robotPu.walk(1.5, 1)
break

case DanceState.Pose:
robotPu.walk(0, 0)
basic.showIcon(IconNames.Heart)
break
}

basic.pause(20)
})

// Helper: schedule next state
function nextState(s: DanceState, delay: number) {
control.setTimeout(() => {
state = s
}, delay)
}

// Dance routine
function startDance() {
state = DanceState.StepLeft
nextState(DanceState.StepRight, 800)
nextState(DanceState.Spin, 1600)
nextState(DanceState.Pose, 2800)
nextState(DanceState.Idle, 4000)
}

// Start dance on button A
input.onButtonPressed(Button.A, function () {
startDance()
})

🎉 你现在知道如何为 Robot PU 使用状态机了

有了这个模式,你可以构建:

  • 舞蹈程序
  • 巡逻循环
  • 迷宫求解序列
  • 多步动画
  • 游戏逻辑
  • 群体行为状态

你还可以:

  • 为舞蹈添加音乐
  • 添加 LED 动画
  • 添加随机舞蹈变体
  • 构建多机器人同步舞蹈