使用参数,从零开始创建一个指令盒脚本

引言

在Choregraphe里,可以编写自己的指令盒,完整地定义其运作。

  • 我们已经在使用指导简单修改指令盒脚本里了解了脚本如何运作。如前面所介绍的,前两步是自动完成,在脚本中不受用户的控制。第二步源于用户创建的链接。但是您可以完全控制第三步,这一步会执行一部分您写入指令盒脚本的编码。 编写脚本时,请不要忘记您定义的是一个模块类的方法,有多种可能性,包括属性、订阅至ALMemory事件等。
  • 指令盒在完成了初始化以后,就可以被加载。每当激活一个输入点时,脚本中就会有一个方法被调用:"onInput_<name>"。通过这种方法,您就可以在输入点被激活时决定进行哪些操作。
  • 编写脚本时,可以随时决定激活一个输出点。需调用的方法名为<outputName>(parameter)

如何操作?

例如:

  • 如果有一个onStopped输出点是“激活”类型,那么调用“onStopped()”就应该可以达到目标;
  • 如果有一个faceDetected(string)输出点,就可以调用faceDetected("Robert")来表示检测到Robert这个人。

在Python里,新指令盒生成的脚本应该如下图所示:

Basic script box

  • initialize(初始化)方法之上,有一个方法,与每个指令盒输入点相关联。
  • 前三行完全是强制性的,对其进行修改会导致不可预测的行为发生。您应该修改的是初始化方法的内容。

    > 可以初始化属性(例如变量、针对其它模块的代理等)。

    > 应该完成所有只想进行一次的操作,因为这个指令盒不会在该行为结束前被销毁。

  • 您会看到一个“onLoad”方法。每当加载指令盒时就会调用这个方法。以下三个事件都可以引起加载指令盒:
    注释:

    由于指令盒加载时会调用这个方法,所以我们强烈建议您不要在这里使用过于繁琐的编码。也就是说,如果一个指令盒的初始化用时过长,会延迟整个行为。如果是在一个时间轴上,那么您甚至可能无法进行实时操作。

    > 开始执行行为,指令盒处于根级。

    > 指令盒包含在一个加载的行为关键帧里。

    > 指令盒包含在另一个指令盒中(即后者的子类为流程图),并且父类指令盒上的一个“onStart”输入点被激活。

  • 您还会看到一个“onUnload”方法。每当指令盒被卸载时就会调用这个方法。以下三个事件都会引起卸载指令盒:

    > 停止行为。

    > 指令盒包含在一个行为关键帧里,而同一层上的另一个关键帧正被加载(由此,包含指令盒的关键帧就要被卸载)。

    > 指令盒包含在另一个指令盒中(即后者的子类为流程图),并且父类指令盒上的“onStop”输入点被激活。

    注释:

    这样,您就可以向其它模块发出警告:这一指令盒将被销毁。目前,由于您不会在简单的指令盒上用到这个功能,因此您可以暂时忘记它。

  • 至于输入点方法,其可能性是无限的。因为不同操作运行在各自的线程里,所以您可以进行复杂的计算而不会影响到播放中的行为。请记住,输出点不会被激活,除非您在编码的某一处写进“onStopped”,明确地要激活输出点。由此,当您使用自己编写的若干个脚本指令盒时,如果没有任何信号输出,那么原因很简单:您忘记在程序完成时调用输出点!使用这一方法,您可以决定何时激活指令盒,从���完成极为复杂的操作(也可以根据需要使用若干个输��点)。

举例

  • 您��望点亮机器人的发光二极管,然而,可以让您完成这一简单操作的Choregraphe插件尚不存在。您在脚本上遇到困难,无法进行下去。那么,您应该做什么呢?首先,阅读有关ALLeds的说明书(即将推出)。ALLeds是一个可以让用户点亮、关闭发光二极管的模块。读过说明书后,您就会现解决方法十分简单。例如,点亮左脚发光二极管需要输入:set("LeftFootLeds", r),r的值在0和1之间。

下面,让我们来运行一个小脚本,使用“with step = 0.02”,来随时间提高和降低发光二极管的亮度。一个典型的Python脚本应该是这样的:

r = 0 while (r+ self.step < 1): r = r +self.step ALLeds.setIntensity ("LeftFootLeds", r) time.sleep(0.01) while (r - self.step > 0): r = r - self.step ALLeds.setIntensity ("LeftFootLeds", r) time.sleep(0.01)

  • 现在,创建一个新指令盒,命名为“RightEarLeds”。
  1. 右击流程图面板,点击添加一个新指令盒
  2. 名称处填入“RightEarLeds”,说明处填入“随时间提高和降低RightEarLeds的亮度”。
  3. 编辑一个图片来代表您的指令盒。您可以在Choregraphe文件夹里选择一个标准图片,或是自行设计图片。
  4. 点击完成.
    注释:

    会自动创建指令盒的3个标准输入项:onStart输入点,onStop输入点和onStopped输出点。您可以通过编辑指令盒来修改或创建输入项。

  5. 双击指令盒,编辑其脚本指令盒。

    > 显示一个几乎是空白的脚本指令盒。

  6. 编写脚本,随时间提高和降低亮度。

    > “RightEarLeds”脚本应如下图所示:

    Modifying the RightEarLeds script

    注释:

    请注意onUnload里的编码,其目的在于当调用onStop或流程图被卸载时,保证指令盒会退出循环。

使用参数

通过参数,您可以自定义指令盒的工作方式。创建了指令盒参数后,您无需编辑任何脚本就可以使用它们。

创建指令盒参数:

  1. 右击指令盒,选择"Edit box"(编辑指令盒)选项。
  2. 首先,我们希望能够改变目前正在编辑的发光二极管组,例如左耳或右耳的发光二极管。操作时,点击“+”图标,在参数表右侧(应该是空白的)添加一个新参数。
  3. 参数名称可以使用如“Leds name”。最好编写一个简短的工具提示来介绍这个参数的作用。我们要添加的参数是一个字符串,所以在"Type"(类型)里选择“String”。
  4. Content (内容)区域,您可以只输入“RightEarLeds”作为默认值,但是由于您有多种选择,因此最好在"Multiple choices" (多种选项)中输入若干个选项。具体操作为:点击 + 图标,然后输入"RightEarLeds",点击OK。然后再点击 + 图标来添加诸如"LeftEarLEds"等选项。
  5. 由于无法输入全部的可能选项(数量过多),我们也可以通过"Custom string possible"(可自定义字符串)选项,直接从指令盒中手动输入另一组,而无需再次输入其属性。
  6. 现在,唯一要做的就是输入脚本。操作时,右击弓形图标,然后选择 "Edit box script" (编辑指令盒脚本)选项。
  7. 移除self.ledsName参考,并将其替换为对一个参数的访问。操作时,选择该参考,然后右击,依次选择Insert Function > Get parameter > leds name(插入函数 > 获取参数 > LED名称)。编写出的脚本应为如下所示:

    > self.getParameter("Leds name")

  8. 脚本结尾处应为如下所示:

    Script using parameters

  9. 现在,您只需点击指令盒上的扳手图标,就可以选择哪一边的耳部LED将会随着时间渐暗。您可以看到,从零开始创建一个指令盒并不是一件太复杂的事情!





Copyright © 2010 Aldebaran-Robotics - 版权所有