第一年 · 第09周
第九章:将Python技能应用到LEGO Spike
在第02周,我们通过复制代码并按下运行按钮来执行了第一个Spike Prime程序。从那以后,你在Google Colab中学习了变量、列表、for循环和函数。本周我们将所有这些技能带回到机器人上。你将不再复制代码,而是自己设计和编写程序。
第1部分:回顾——机器人是如何工作的
还记得第02周的第一个程序吗?让我们再看一次:
from hub import port import runloop, motor_pair async def main(): motor_pair.pair(motor_pair.PAIR_1, port.C, port.D) await motor_pair.move_for_degrees(motor_pair.PAIR_1, 360, 0, velocity=360) runloop.run(main())
这个程序做了三件事:
- 导入——加载我们需要的库(
hub、runloop、motor_pair)。 - 配对电机——告诉Hub哪两个端口连着轮子。
- 移动——让机器人转动轮子360度。
第2部分:用变量调整机器人
在第02周,我们把数字直接写在代码里。如果想改速度,就得去代码中间找到那个数字然后修改。当程序变长时,这样做很容易出错。
更好的方法:把所有可调参数放在程序最上面,作为变量。这叫做配置块。
# ── 配置块 ── SPEED = 360 # 每秒多少度 DRIVE_DEGREES = 720 # 向前走多远(轮子转的度数) TURN_DEGREES = 360 # 转弯多少度(轮子转的度数)
现在,当你想让机器人走得更远或更慢时,只需要改变一个地方的数字。
第3部分:用函数封装可重用的动作
在第07周,你写过Python函数来计算误差。现在我们用函数来封装机器人的动作。与其每次都写一长串电机命令,不如把它包装成一个函数:
async def drive_straight(degrees): await motor_pair.move_for_degrees( motor_pair.PAIR_1, degrees, 0, velocity=SPEED ) async def turn_right(degrees): await motor_pair.move_for_degrees( motor_pair.PAIR_1, degrees, 100, velocity=SPEED ) async def turn_left(degrees): await motor_pair.move_for_degrees( motor_pair.PAIR_1, degrees, -100, velocity=SPEED )
现在你的主程序变得像自然语言一样易读:
async def main(): motor_pair.pair(motor_pair.PAIR_1, port.C, port.D) await drive_straight(DRIVE_DEGREES) await turn_right(TURN_DEGREES) await drive_straight(DRIVE_DEGREES)
第4部分:用For循环实现重复路线
假设你想让机器人走一个正方形——向前走,右转90度,重复四次。不用循环,你得把同样的代码写四遍:
# 不用循环——重复又无聊! await drive_straight(DRIVE_DEGREES) await turn_right(TURN_DEGREES) await drive_straight(DRIVE_DEGREES) await turn_right(TURN_DEGREES) await drive_straight(DRIVE_DEGREES) await turn_right(TURN_DEGREES) await drive_straight(DRIVE_DEGREES) await turn_right(TURN_DEGREES)
用for循环,只需要两行:
# 用循环——简洁! for i in range(4): await drive_straight(DRIVE_DEGREES) await turn_right(TURN_DEGREES)
多边形挑战
我们可以用一个变量控制边数,让机器人走出任何正多边形:
SIDES = 6 # 改这个数字试试! for i in range(SIDES): await drive_straight(DRIVE_DEGREES) await turn_right(360 // SIDES)
第5部分:用列表规划多步任务
如果你的路线不是一个简单的形状呢?比如你需要:向前走500度,右转,向前走300度,左转,向前走700度。你可以把这些步骤存在列表里:
# 每一步:(距离度数, 转弯方向, 转弯度数) mission = [ (500, "right", 90), (300, "left", 45), (700, "right", 90), ] for step in mission: distance = step[0] direction = step[1] angle = step[2] await drive_straight(distance) if direction == "right": await turn_right(angle) else: await turn_left(angle)
这和第05周中遍历向量分量的方式完全相同——只不过现在列表里存的是机器人的动作指令!
第6部分:完整程序
让我们把所有内容组合成一个完整的程序。这个程序让机器人走一个正方形:
from hub import port import runloop, motor_pair # ── 配置块 ── SPEED = 360 DRIVE_DEGREES = 720 SIDES = 4 async def drive_straight(degrees): await motor_pair.move_for_degrees( motor_pair.PAIR_1, degrees, 0, velocity=SPEED ) async def turn_right(degrees): await motor_pair.move_for_degrees( motor_pair.PAIR_1, degrees, 100, velocity=SPEED ) async def main(): motor_pair.pair(motor_pair.PAIR_1, port.C, port.D) for i in range(SIDES): await drive_straight(DRIVE_DEGREES) await turn_right(360 // SIDES) runloop.run(main())
展望未来
本周你把在Colab里学到的Python技能带到了真实的机器人上——变量、函数、循环和列表都有了实际用途。在接下来的几周里,我们将加入传感器,让机器人能够感知周围环境并做出反应,而不是盲目地按照预设路线行驶。