移动电机是EV3的核心。机器人需要移动的能力,因此你需要知道它是如何完成的。请参阅文档 EV3 Firmware Developer Kit 中的第 4.9 部分,以获得与电机相对应的操作的第一印象。几乎所有这些都以相同的两个参数开头:
LAYER:如果组合多个 EV3 brick 作为单个机器,则声明其中一个是主机,最多3个额外 brick 作为主机从机。然后将操作发送到主机,主机将其发送给主机从机。这就是 LAYER 的含义。Layer 0x|00| 是主机,layers 0x|01|,0x|02| 和 0x|03| 是它的可选从机。在没有从机的标准情况下,我们将设置 LAYER = 0x|00|。我们的直接命令代码可以连接多个 EV3 设备。因此,我认为不需要不同的参数 LAYER 值。
NO 或 NOS:电机端口以字母 A,B,C 和 D 标识。在直接命令的层面,你可以通过数字命名它们,A = 0x|01|,B = 0x|02|,C = 0x|04| 和 D = 0x|08|。如果你将这些数字写为二进制表示,则 A = 0b 0000 0001,B = 0b 0000 0010,C = 0b 0000 0100 和 C = 0b 0000 1000,你看,后半个字节可以解释为一系列的四个标志。你可以组合这些标志。如果你处理端口 A 和 C 的电机操作,则设置 NOS = 0x|05| 或 0b 0000 0101。如果参数名称为 NO,则只能处理单个电机端口。NOS是说,你可以处理一个或多个端口。
启动和停止电机
将一些电机插入你选择的端口,然后以全功率启动它们。这通过以下直接命令完成:
过了一段时间,你,你的父母,兄弟姐妹或孩子会对全动力马达的声音感到紧张。如果你是一个爱好和平的人,你应该发送以下直接命令:
我们看到了三个新操作:
opOutput_Power = 0x|A4|,参数是
- LAYER
- NOS
- POWER:指定输出功率 [-100 – 100 %](负值意味着相反的方向)
opOutput_Start = 0x|A6|,参数是
- LAYER
- NOS
opOutput_Stop = 0x|A3|,参数是
- LAYER
- NOS
- BRAKE:指定制动级别 [0:浮动,1:制动]。这不是被动制动器,其中电动机固定在其位置上。它是一个主动的,电机试图回到原来的位置,这需要能量!
通过这三个操作,我们可以启动和停止电机。我们还应该讨论另一个,它设定了极性。通常,电动机的运动以前后方向描述,并且使用正数和负数。如果我们的机器结构导致极性相反,则有一个操作,可以改变它:
- opOutput_Polarity = 0x|A7|,参数是
- LAYER
- NOS
- POLARITY:指定极性 [-1, 0, 1]
- -1:电机将向后运行
- 0:电机将反方向运行
- -1:电机将向前运行
定义速度而不是功率通常是更好的选择。幸运的是,乐高电机固定的电机,我们可以通过以下操作轻松定义电机运动的恒定速度:
- opOutput_Speed = 0x|A5|,参数是
- LAYER
- NOS
- SPEED:指定输出速度 [-100 – 100 %](负值意味着相反的方向)
请构造一辆由两个电机驱动的车辆,一个用于左侧,另一个用于右侧。精心设计的例子是:
- http://robotsquare.com/2015/10/06/explor3r-building-instructions
- http://robotsquare.com/wp-content/uploads/2013/10/45544_educator.pdf
- http://www.lego.com/en-gb/mindstorms/build-a-robot/track3r
- http://www.lego.com/en-gb/mindstorms/build-a-robot/robodoz3r
但一个简单的也将满足我们的需求。将右侧电机连接到端口 A,将左侧电机连接到端口 D,并发送以下直接命令:
希望你的车辆以低速直行。使用上面的直接命令(opOutput_Stop)来停止它。
遥控车辆
现在是编写实际应用程序的时候了。使用遥控 EV3 车辆给你的朋友或孩子留下深刻印象。我们从一个简单的遥控器开始,并使用键盘箭头键来改变速度和方向。首先将新操作添加到 EV3 类,然后编写远程控制程序。像往常一样,我已经以python3 完成了它:
一些说明:
- 我使用模块
curses
来实现键盘事件的事件处理程序。 - 方法
wrapper
控制资源键盘和终端。它改变终端的行为,创建一个窗口对象并调用函数main
。 - 函数
main
将一些文本写入终端,然后等待键事件(方法getch
)。 - 如果其中一个相关键命中,则调用函数
react
,键<q>
或<Ctrl-c>
打破循环。 - 变量
speed
定义了更快轮子的速度。 - 变量
turn
定义方向。值 0 表示直行,正值表示左转,负值表示右转。转弯的绝对值大意味着转弯的半径小。最大值+200 和最小值 -200 意味着在原地盘旋。在下一课中,我们将回到驱动转弯的这个定义。 - 我在第 5 步改变了
speed
和turn
。这似乎是精确度和反应速度之间的良好折衷。 - 也许,你的车辆结构需要改变两个车轮的极性。这由注释掉的代码完成。
- 右轮连接到端口 A,左侧连接到端口 D。
- 对于低速,由于四舍五入到整数值,转弯半径的精度变得更差。
中断作为一种设计理念
上一课,我们将中断与不耐烦和乖巧的人进行了比较。本课程表明,这种行为恰恰是一种切实可行的设计理念。
遥控程序发送无限的命令,如果不被下一个命令中断,它将永久地移动电机。控制驾驶的人类希望纠正立即生效。这是绝对正确的,新命令会中断旧命令。
该设计概念的另一个积极方面是直接命令的执行时间短。它们不耗时。电机的运动持续很长时间,但是当电机获得新参数时,直接命令已经执行完成。控制立即返回,程序是自由的,以执行下一个任务。资源 EV3 设备未被阻塞,它可用于下一个直接命令。
你已经看到了如何编码远程控制的中断过程。中心部分是一个请求关键事件的循环。如果相关的按键事件发生,则调用一个函数,该函数更改运动的参数并向 EV3 设备发送直接命令。
当我们在 c’’(上一课)中玩三合一时,我们避免了中断。我们有一个固定的所有音调时间表。我们的意见是,每次中断都会扰乱计划,需要加以防范。在绘制三角形时,我们已经讨论了两种时序选择,通过直接命令或本地程序。也可以使用本地程序中的调度并使用中断来播放三元组。这是获得正确时序的替代方法:
|
|
此版本还实现了固定的调度,但时间发生在程序中而不是 EV3 设备上(在直接命令中)。同样,这有一定的优势,它不阻塞 EV3 设备。只要我们一次只执行一个任务,阻塞就无关紧要了。如果我们试图结合独立的声音和点击驱动,且并行执行任务,则本地时序和中断是必须的。
如果我们在上面的程序中设置 sync_mode == SYNC,数据流量会增长,但我们不会听到任何差异。值得反思的是,该程序同步运行,因为没有直接命令是耗时的。sync_mode == ASYNC 或 sync_mode == STD 是为异步执行设计的,但我们也可以使用这些设置编写同步执行代码。异步执行仅在直接命令耗时(时间由直接命令完成)且本地程序不等待直接命令结束时。中断有助于避免耗时的直接命令,并且是同步执行。
继承 EV3
到目前为止,我们直接在我们的程序中编写了操作。这需要封装和抽象。我想特化类,一个用于带两个驱动轮的车辆,一个用于音调和音乐等等。设计应该允许它们平并行使用。我的解决方案是大量的 EV3 类的子类,它们都与同一个 EV3 设备通信。这就是说,它们必须共享资源。为了实现这一点,我修改了 EV3 类的构造函数:
|
|
代码是:
一些注解:
- 有两种创建类 EV3 的新实例的方式:
- 和以前一样,使用参数
protocol
和host
调用构造函数以获取新连接。 - 另一种方法是使用现有的 EV3 对象作为参数
ev3_obj
调用它,使用其中的连接。
- 和以前一样,使用参数
- 这不仅限于连接。对于将来的扩展,我们可以共享任何资源。
- 每个类都有自己的
_verbosity
和_sync_mode
。这是 OK 的,但我们使消息计数器_msg_cnt
成为一个类属性:12class EV3:_msg_cnt = 41
考虑到这一点,我编写了类 TwoWheelVehicle
,这里是它的构造函数:
我添加了两个方法:
和
我们需要三个属性:
就是这样,我们有了一个新类 TwoWheelVehicle
,它具有这样的 API:
从现在开始,当我们使用两个驱动车轮移动车辆时,我们将使用ClassWheelVehicle
。实际上这不仅仅是一个练习,而是一个真实的东西,但下一课,我们将为这个类添加功能。你可能会问,如果努力和利益真的是平衡的话。但是看,我们的程序变短了:
如果你下载了 ev3-python3 的模块 ev3_vehicle.py
,你需要以两个额外的参数 radius_wheel
和 tread
调用 TwoWheelVehicle
的构造函数。目前你可以将它们设置为任何正值。
结论
现在我们知道了,如何移动电机,我们获得了两个重要设计概念的经验,即中断和子类化。此外我们编写的东西像个真正的应用程序了,一个车辆的遥控器。
我希望,你的遥控器工作良好,并使你成为一个技术明星。我们即将结束本课程。浏览文档 EV3 Firmware Developer Kit 告诉您,移动电机存在许多额外的操作。其中大多数是为了精确,同步和平滑的运动。这将是我们下一课的主题。我希望能再次见到你。