此页面由 AI 自动翻译。查看英文原版

本页目录

  • 如何放置
  • 输入和输出
  • 用法
  • 与 GPIO 接口
  • 时间同步
  • 使用 DepthAI
  • 可用模块和库
  • 功能示例
  • 参考

Script

Supported on:RVC2RVC4
Script 节点允许用户在设备上运行自定义 Python 脚本。由于计算资源限制, script 节点不应用于繁重的计算(例如图像处理/计算机视觉),而应用于管理流水线流程(业务逻辑)。 示例用例包括控制 ImageManip ColorCamera SpatialLocationCalculator 等节点, 解码 NeuralNetwork 结果,或与 GPIO 接口。

如何放置

Python

Python
1pipeline = dai.Pipeline()
2script = pipeline.create(dai.node.Script)

C++

C++
1dai::Pipeline pipeline;
2auto script = pipeline.create<dai::node::Script>();

输入和输出

用户可以根据需要定义任意数量的输入和输出。输入和输出可以是任何 components_messages 类型。

用法

Python

Python
1script = pipeline.create(dai.node.Script)
2script.setScript("""
3    import time
4    import marshal
5    num = 123
6    node.warn(f"Number {num}") # Print to host
7    x = [1, "Hello", {"Foo": "Bar"}]
8    x_serial = marshal.dumps(x)
9    b = Buffer(len(x_serial))
10    while True:
11        time.sleep(1)
12        b.setData(x_serial)
13        node.io['out'].send(b)
14""")
15script.outputs['out'].link(xout.input)
16
17# ...
18# After initializing the device, enable log levels
19device.setLogLevel(dai.LogLevel.WARN)
20device.setLogOutputLevel(dai.LogLevel.WARN)

C++

C++
1auto script = pipeline.create<dai::node::Script>();
2script->setScript(R"(
3    import time
4    import marshal
5    num = 123
6    node.warn(f"Number {num}") # Print to host
7    x = [1, "Hello", {"Foo": "Bar"}]
8    x_serial = marshal.dumps(x)
9    b = Buffer(len(x_serial))
10    while True:
11        time.sleep(1)
12        b.setData(x_serial)
13        node.io['out'].send(b)
14)");
15script->outputs["out"].link(xout->input);
16
17// ...
18// After initializing the device, enable log levels
19device.setLogLevel(dai::LogLevel.WARN);
20device.setLogOutputLevel(dai::LogLevel.WARN);

与 GPIO 接口

在 script 节点中,您可以使用 GPIO 模块与 VPU 的 GPIO 进行交互。当前支持的功能包括:
Python
1# Module
2import GPIO
3
4# General
5GPIO.setup(gpio, dir, pud, exclusive)
6GPIO.release(gpio)
7GPIO.write(gpio, value)
8GPIO.read(gpio)
9
10# Interrupts
11GPIO.waitInterruptEvent(gpio = -1) # blocks until any interrupt or interrupt by specified gpio is fired. Interrupts with callbacks are ignored here
12GPIO.hasInterruptEvent(gpio = -1) # returns whether interrupt happened on any or specified gpio. Interrupts with callbacks are ignored here
13GPIO.setInterrupt(gpio, edge, priority, callback = None) # adds interrupt to specified pin
14GPIO.clearInterrupt(gpio) # clears interrupt of specified pin
15
16# PWM
17GPIO.setPwm(gpio, highCount, lowCount, repeat=0) # repeat == 0 means indefinite
18GPIO.enablePwm(gpio, enable)
19
20# Enumerations
21GPIO.Direction: GPIO.IN, GPIO.OUT
22GPIO.State: GPIO.LOW, GPIO.HIGH
23GPIO.PullDownUp: GPIO.PULL_NONE, GPIO.PULL_DOWN, GPIO.PULL_UP
24GPIO.Edge: GPIO.RISING, GPIO.FALLING, GPIO.LEVEL_HIGH, GPIO.LEVEL_LOW
下面是一个示例,演示如何在 Script 节点中从主机切换 GPIO 引脚 40。在 OAK-SoM-Pro 上, GPIO 40 驱动两个 4 通道摄像头的 FSYNC 信号,我们为此目的使用了以下代码。
Python
1import GPIO
2MX_PIN = 40
3
4ret = GPIO.setup(MX_PIN, GPIO.OUT, GPIO.PULL_DOWN)
5toggleVal = True
6
7while True:
8  data = node.io['in'].get()  # Wait for a message from the host computer
9
10  node.warn('GPIO toggle: ' + str(toggleVal))
11  toggleVal = not toggleVal
12  ret = GPIO.write(MX_PIN, toggleVal)  # Toggle the GPIO

时间同步

Script 节点可以访问设备(内部)时钟以及同步后的主机时钟。主机时钟以低于 2.5ms 的精度(在 1σ 下)与设备时钟同步,主机时钟同步
Python
1import time
2interval = 60
3ctrl = CameraControl()
4ctrl.setCaptureStill(True)
5previous = 0
6while True:
7    time.sleep(0.001)
8
9    tnow_full = Clock.nowHost() # Synced clock with host
10    # Clock.now() -> internal/device clock
11    # Clock.offsetToHost() -> Offset between internal/device clock and host clock
12
13    now = tnow_full.seconds
14    if now % interval == 0 and now != previous:
15        previous = now
16        node.warn(f'{tnow_full}')
17        node.io['out'].send(ctrl)

使用 DepthAI 消息

脚本节点会自动导入 depthai 模块。您可以创建新的 depthai 消息并为其赋值,例如:
Python
1buf = Buffer(100) # 为 Buffer 消息分配 100 字节
2
3# 创建 CameraControl 消息,设置手动对焦
4control = CameraControl()
5control.setManualFocus(100)
6
7imgFrame = ImgFrame(300*300*3) # 包含 300x300x3 字节的缓冲区

可用模块和库

RVC2

可用模块
Text
1"posix", "errno", "pwd", "_sre", "_codecs", "_weakref", "_functools", "_operator",
2"_collections", "_abc", "itertools", "atexit", "_stat", "time", "_datetime", "math",
3"_thread", "_io", "_symtable", "marshal", "_ast", "gc", "_warnings", "_string", "_struct"
LEON_CSS 可用模块:
Text
1"binascii", "_random", "_socket", "_md5", "_sha1", "_sha256", "_sha512", "select",
2"array", "unicodedata
Text
1"__main__", "_collections_abc", "_frozen_importlib", "_frozen_importlib_external",
2"_sitebuiltins", "abc", "codecs", "datetime", "encodings", "encodings.aliases",
3"encodings.ascii", "encodings.latin_1", "encodings.mbcs", "encodings.utf_8", "genericpath",
4"io", "os", "posixpath", "site", "stat", "threading", "types", "struct", "copyreg",
5"reprlib", "operator", "keyword", "heapq", "collections", "functools", "sre_constants",
6"sre_parse", "sre_compile", "enum", "re", "json", "json.decoder", "json.encoder",
7"json.scanner", "textwrap"
LEON_CSS 库:
Text
1"http", "http.client", "http.server", "html", "mimetypes", "copy", "shutil", "fnmatch",
2"socketserver", "contextlib", "email", "email._encoded_words", "email._header_value_parser",
3"email._parseaddr", "email._policybase", "email.base64mime", "email.charset",
4"email.contentmanager",  "email.encoders", "email.errors", "email.feedparser",
5"email.generator", "email.header", "email.headerregistry", "email.iterators", "email.message",
6"email.parser", "email.policy", "email.quoprimime", "email.utils", "string", "base64",
7"quopri", "random", "warnings", "bisect", "hashlib", "logging", "traceback", "linecache",
8"socket", "token", "tokenize", "weakref", "_weakrefset", "collections.abc", "selectors",
9"urllib", "urllib.parse", "calendar", "locale", "uu", "encodings.idna", "stringprep"
模块(module)和库(library)的区别在于:模块是预编译的 C 源代码,带有 Python 绑定;而库是 Python 源代码,打包成库并预编译成 Python 字节码(在加载到我们的固件之前)。 在 LEON_CSS 上可用的网络/协议模块/库 只能在 OAK POE 设备上使用。 您可以指定脚本将在哪个处理器上运行,例如,对于 LEON_CSS:
Python
1script = pipeline.create(dai.node.Script)
2script.setProcessor(dai.ProcessorType.LEON_CSS)

RVC4

OAK4 上的脚本节点使用基础 Python 环境,这意味着基础 Python 环境中所有可用的模块和库在脚本节点中也可用。 要添加其他模块或库,您可以在基础 Python 环境中使用 pip 命令。

功能示例

参考

class

dai::node::Script

variable
InputMap inputs
Inputs to Script node. Can be accessed using subscript operator (Eg: inputs['in1']) By default inputs are set to blocking with queue size 8
variable
OutputMap outputs
Outputs from Script node. Can be accessed subscript operator (Eg: outputs['out1'])
function
void setScriptPath(const std::filesystem::path & path, const std::string & name)
Specify local filesystem path to load the script
Parameters
  • path: Filesystem path to load the script
  • name: Optionally set a name of this script, otherwise the name defaults to the path
function
void setScript(const std::string & script, const std::string & name)
Sets script data to be interpreted
Parameters
  • script: Script string to be interpreted
  • name: Optionally set a name of this script
function
void setScript(const std::vector< std::uint8_t > & data, const std::string & name)
Sets script data to be interpreted
Parameters
  • data: Binary data that represents the script to be interpreted
  • name: Optionally set a name of this script
function
std::filesystem::path getScriptPath()
function
std::string getScriptName()
function
void setProcessor(ProcessorType type)
Set on which processor the script should run
Parameters
  • type: Processor type - Leon CSS or Leon MSS
function
ProcessorType getProcessor()
Get on which processor the script should run
Returns
Processor type - Leon CSS or Leon MSS
function
void buildInternal()
function
void buildStage1()
inline function
DeviceNodeCRTP()
inline function
DeviceNodeCRTP(const std::shared_ptr< Device > & device)
inline function
DeviceNodeCRTP(std::unique_ptr< Properties > props)
inline function
DeviceNodeCRTP(std::unique_ptr< Properties > props, bool confMode)
inline function
DeviceNodeCRTP(const std::shared_ptr< Device > & device, std::unique_ptr< Properties > props, bool confMode)

需要帮助?

请前往 Discussion Forum 获取技术支持或提出您可能有的任何其他问题。