Omar Rizwan上周在博客里记录了Dynamicland近期的探索和方向: Notes from Dynamicland: programming Raspberry Pis,为我们钩画了极为令人振奋的未来。

Dynamicland的目标是重塑人机交互的方式,重塑计算机。

下边是我的翻译。

摘要

  • 树莓派(Raspberry Pi)是一种小型的单片机计算机;它可以通过其引脚和接口与外部硬件通信。
    • Pi(树莓派的简称)展示了我们可以如何分解大型的Realbox机器,使Dynamicland成为许多计算机、传感器和执行器的生态系统,而不是服务器上的软件。
    • “……Pi之于Dynamicland正如USB接口之于笔记本电脑:这就是我将东西插入Dynamicland的方式。”
  • 使用Realtalk来打开/关闭Pi上LED的最小示例。
  • 解释Realtalk的“反应数据库”(reactive database)编程模型; 它如何使动感桌(dynamic table)中的Pi编程变得异常简单。Pi的编程与Dynamicland中的任何其他编程没什么区别。
    • 通过向Pi发送完整程序来进行远程控制,而不是用一些动力不足的控制语言与之通信。
  • 关于Pi如何在未来发挥作用的猜想。

Realtalk 与 树莓派

如今,Dynamicland有一系列的动感桌:

正在运行Gapminder demo的动感桌

每张桌子都由一个’Realbox’机器驱动, ‘Realbox’机器充当计算引擎,它运行着Linux,它能执行桌子上的纸页(纸页上的功能代码),并连接到摄像机和投影仪。

安装在天花板上的Realbox。我争辩说,这只是一个权宜之计

Realbox都通过Realtalk协议联合在一起,因此桌子可以在整个房间内进行通信并共享数据和程序。

目前Realbox体系:Realbox驱动的桌子,由Realtalk协议联网在一起

我想说我们不应该需要那些Realboxes(以及它们包含的复杂软件栈),它们只是一个权宜之计。

Realboxes功能是什么?大多数Realtalk程序(比如我以前的Geokit)都使用摄像头作为输入和投影仪作为输出。

带有简单输入和输出的海报([原图](https://rsnous.com/posts/notes-from-dynamicland-programming-raspberry-pis/input-output-board.jpg)),使用了摄像头和投影仪

Realbox有两个目标:

  • 通过USB和HDMI与摄像头和投影仪对话(硬件抽象,输入输出(I/O),‘控制’)
  • 执行程序(‘计算’, ‘模拟’)

考虑一下程序如何在你的笔记本电脑上运行:主要使用鼠标和键盘来输入,使用屏幕来输出,程序在笔记本电脑主板上的CPU上执行。

但是,Realtalk的编程模型比这种特殊配置更加通用和强大。它根本不是关于摄像头、投影仪、彩色斑点或纸页。这是一个协议,用于各类动态的、物理的、可再编程的计算。

该协议不需要像Realbox这样的大型Linux计算机来运行。Realtalk在小型计算机上同样可以运行(如树莓派):

树莓派(左)和Realbox(右)运行相同的Realtalk系统!

如果你不熟悉树莓派的话,我们简单介绍一下,树莓派是一块带有Wi-Fi和USB接口的小型单片机计算机,此外它拥有通用数字I/O引脚。它像我们日常所说的“计算机”一样功能齐全: 人们经常在其上运行桌面Linux操作系统,并插入显示器、鼠标和键盘。

树莓派3(来自[维基百科](https://en.wikipedia.org/wiki/Raspberry_Pi#Connectors))

如果我们有这些小型Realtalk主机,为何我们还要将桌面上的所有内容连接到大型的Realbox上?每个传感器(如摄像机)和每个执行器(例如投影仪)都可以连接到它自己的Pi,或类似的"接口计算机"上 ,它可以在电信号和Realtalk语句之间进行转换。而这些Pi可以通过Realtalk协议联合在一起。

未来的Realtalk生态系统,每个传感器和执行器都连接到自己的“接口计算机”上

Pi能够与物理世界进行很好的连接,因为它具有丰富的接口和引脚,可用于与传感器和执行器通信。你可以接入电机并使Pi驱动🚗或 者连接触摸传感器👆。它与Dynamicland的目标非常契合,它是我们跳出了摄像头-投影仪模式。

Dynamicland是一个生态系统,而不是在Linux设备上运行的一段代码,它可以很容易地连接新的传感器和执行器,并且易于理解和修改单个部件。

进一步设想一下不需要投影仪和摄像头的未来,今天我们打印的页面,在未来变为纸片薄的计算机,而不是木浆。代码存在于真实可见的物理世界,它便宜且不可变,因此它们保留了我们想要的Dynamicland属性。但是这些页面本身拥有计算能力,而不需要高高在上的摄像头-投影仪系统。

未来的Realtalk生态系统,具有“智能页面”而非摄像头-投影仪

这些页面如何相互通信?它们又如何与周围的其他硬件相互通信?你如何与分布式计算机进行交互?那台计算机又如何赋予你权力?

您可以将Dynamicland视为未来原型的尝试,并将Realtalk视为它可能是如何工作的一种建议:不是一个操作系统、网络协议、数据库、编程语言或用户界面范例,而是所有这些中的一部分。

今天与Pi沟通

我们已经在Dynamicland中建立了网络概念; 我们已经拥有了由独立的Realtalk主机驱动的独立动感桌,所有这些都使用Realtalk协议相互通信。你可以在桌子之间轻松地进行通信。

现在,为了与Pi交谈,我们将Realtalk主机软件和Lua解释器移植到Pi,因此Pi在每个桌子上运行着相同的基础软件。

Pi变成了“虚拟桌子”。在桌子 <-> Pi之间的对话与 桌子 <-> 其他桌子之间的对话并无不同。

今天的Pi:一个“虚拟桌子”,与Realboxes地位相同

下边将展示一个小例子,在Pi上切换LED,然后解释它是如何工作的以及它将来可能做些什么。

Dynamicland中的Pi

让我们看看树莓派现在Dynamicland中的样子。我已将Pi附加到纸页(18858),因此房间总是看得到纸页并知道Pi的确切位置。这个纸页就像是树莓派的"句柄"(handle); 我可以在其他程序中引用Pi的纸页(id)来控制它。

左边是未通电的Pi,右边是已启动且已连接的Pi

Pi打开并连接(wifi?)后,页面变为绿色。接着,Pi的页面也会显示其标识符<Processor pi-74a6>74a6是Pi的MAC地址的最后两个字节,每个Pi都是唯一的。

切换activity LED

activity LED是Pi上的一个LED灯,平时用于指示Pi的工作状态。

现在我想在Pi上切换activity LED的状态。切换activity LED是我们可以对Pi的最简单又可见的事情。因此它适合用来测试Pi-Realtalk的集成。

activity LED很难被发现, 它是Pi板子上红色LED上方的绿色LED:

Pi上的绿色活动LED(当前已打开)

我抓住我的控制activity LED程序(也是一个纸页),它生发出一根绿色的胡须。当我让这根胡须去戳Pi时,Pi的activity LED将会打开; 否则,它将熄灭。(我稍后会更详细地解释这个程序。)

使用程序切换activity LED的状态

实际上,这个程序不仅限于那个Pi:它适用于桌面上的任何Pi。程序会打开胡须戳中的Pi上边的activity LED,而关闭其他Pi上边的activity LED。

让我们在多个Pi上尝试

在多个Pi上activity LED的状态

如果没有Realtalk系统,你要如何制作这种LED切换器?听起来很痛苦。也许你会ssh到每个Pi中,编写并执行一些Python脚本。(如果随后要更改代码,你要如何将更改部署到所有Pi上?)你需要实现对某些指针对象的跟踪以便控制它们。你需要一些通信协议来将信息从跟踪系统传送到所有Pi上。你需要手头的笔记本电脑来完成所有编程。如果你想添加第四、第五或第十个Pi呢,又该怎么办?

你首先会有这些想法吗?

LED切换器的工作原理

为了展示这个程序如何在桌面和Pi上工作,我需要解释一下Realtalk。

Realtalk数据库

Realtalk是一个编程系统,但它也是一种反应型数据库(reactive database)。

运行着Realtalk的每台机器都知道每帧中一组一致的Realtalk 语句(statements)(如'30帧/秒’)。语句是Realtalk程序的声明(claim)或愿望(wish)。

从我之前的Geokit帖子中考虑这个最小的例子:

1
2
3
4
5
6
7
8
9
-- Page 17813
-- Made-up claim demo
Claim (you) blahblahblah.

-- Page 17814
-- Made-up claim when demo
When /page/ blahblahblah:
    Wish (page) is highlighted "blue".
End
最小的Claim/When/Wish示例来说明数据库

当页面17813和17814同时在桌子上面朝上时,桌子数据库将每帧包含这些语句:

如果我移走了下边一张页面(17814),后续帧中的数据库将只包含

因为底下的页面不再是“显示蓝色”的愿望(wish)了。

如果我移走了顶部页(17813),但保留了底部页,数据库将不含有这两个语句。由于Realtalk的反应式设计,删除blahblahblah声明会自动删除其依赖,即“显示蓝色”的愿望。

即使底部页仍留在桌面上,它的When也不再匹配任何blahblahblah声明,因此底页不再产生愿望(wish)。

信息应该流经Realtalk数据库

页面通过在Realtalk数据库中读取和写入语句进行通信,而不是通过调用函数或定义变量。

我相信这些机制的灵感来自元组空间黑板概念,以及Datalog,但我对这段历史知之甚少。你可以将Realtalk语句(statements)(声明和愿望)视为存在于“黑板”之上,所有程序都盯着这个“黑板”。然而,在Realtalk中,语句不仅仅是抽象数据; 他们应该关注现实世界。我们的“元组空间”(tuple space)模仿了桌子的社交空间,在这儿,每个人都可以看到和听到对方,同样地,Realtalk中的程序都可以看到彼此的声明(statements)。

只要信息流经Realtalk数据库,之后就可以轻松检查、拦截、跟踪、调试和扩展!查询该数据库的进程将自动对更改进行实时响应。我经常制作一些一些小工具 与我手头的程序互动,交互式地探索它。

相反,如果你坚持使用传统的函数和变量,那么你的程序将被封闭,并且对外部世界不透明。传统上构建的程序是静态的:除非您明确地对其进行编码以进行更新,否则它不会响应输入的更改(或周围程序的更改)。

在我们的例子中,桌子和Pi是两个独立的Realtalk主机,因此每个(在Realtalk的当前实现中)都有自己的数据库(帧速率和每帧语句集)。

请注意,Pi并未连接到摄像机,并且无法独立查看任何程序,因此Pi基本上是惰性的(没有外部刺激):在别处运行的程序必须手动将程序和语句转发给Pi,以使其执行或了解外部世界的任何事情。

切换器(toggler)的代码

切换器(toggler)是我们前头图片里带绿色胡须的程序。

这是我之前的LED切换程序。

我正在使用的程序: 切换Pi 的activity LED的状态

你了解Unix上的fork吗?上边这个程序与Unix上使用fork的程序谜之相似:它与自己的分身并行运作。一个部分在这里运行,另一个部分在那里运行。

你应该了解的是,processor是一个全局变量,它标识着底层的Realtalk机器:

  • 如果页面在桌面上运行,那processor形如
  • 如果页面正在Pi上运行,processor形如

该页面由两个代码块组成。该页面同时在Pi和动感桌上执行 ; 每个代码块的第一行检查页面正在执行的处理器(processor)类型,每个代码块据此决定是否运行。

  • 上边的代码块: if not is_pi(processor) then ..., 像一个普通的Realtalk纸页运行在桌子上,全局函数is_pi检查processor是否是Pi.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
if not is_pi(processor) then
    -- This block runs on the realbox (the table).

    When /pi/ is pi /something/:
        -- for each Pi on the table,
        Wish (you) runs remotely on (pi).

        When (you) points "up" at (pi):
            Wish (pi) sets led brightness to "1".
        Otherwise:
            Wish (pi) sets led brightness to "0".
        End
        Wish (processor) shares statements with relation
            "_ wishes _ sets led brightness to _.".
    End
end
  • 找到桌子所有Pi的句柄(handles),对于每个Pi,

    • 将自身运行在Pi上: Wish (you) runs remotely on (pi)., 接着
    • 投射绿色胡须:When (you) points "up" at (pi),如果那个胡须碰到pi,那么希望(wish)它的LED开启; 否则,希望(wish)它的LED关闭.
  • Wish (processor) shares statements with relation "_ wishes _ sets led brightness to _"联合该形式的所有愿望。不仅仅停留在桌子数据库中,也希望(wish)被转发到房间中所有其他Realtalk主机的数据库,包括Pi!

当我指向我的LED切换器时pi-74a6,顶部块可能会在桌子数据库中生成这些语句(假设桌子本身由realbox7驱动):

底部块, When /someone/ wishes (you) runs remotely on (processor): ... runs只运行在Pi上。

1
2
3
4
5
6
7
8
9
When /someone/ wishes (you) runs remotely on (processor):
    -- This block runs on the Pi itself.

    os.execute('echo gpio | sudo tee /sys/class/leds/led0/trigger')
    When /pi/ is processor (processor),
         /someone/ wishes /pi/ sets led brightness to /value/:
        os.execute('echo '..value..' | sudo tee /sys/class/leds/led0/brightness')
    End
End

顶部块让这些程序自身运行在每个Pi上,它还在房间内共享一些语句到每个Pi的数据库(右)中。我们可以使用When来匹配哪些语句应该在Pi上运行,哪些该在桌子上运行。

从Realbox(左)到Pi(右)共享的语句

底部代码块的第一个检查: When /someone/ wishes (you) runs remotely on (processor)实质上是检查我们执行的原因。

它之所以运行,是因为有人把它放在桌子上,或者顶部块(放在桌子上的)希望它在当前设备“远程运行” 。如果是后者,那么它必须在Pi上运行; 因此,如果这个When被匹配,说明它正运行在Pi中。

现在这段代码正在Pi上执行,可以使用普通的Unix命令来控制activity LED,就好像我们在Pi上的终端中键入命令一样。

一旦我们开始,我们就会运行一个echo | sudo tee命令将activity LED初始化为GPIO模式,以便我们以后可以控制它。

接着,每当得到一个wish(来自桌子,如图中所示)来设置我们的led brightness to some value,,就运行一个echo | sudo tee实际设置LED亮度的命令。

我确实有一种高级语言来处理: Wish (pi) runs unix command,你通常不需要这种明确声明run remotely的模式(上边两个代码块的模式)。但我想在这里演示一些基本原理; 更高级别的接口是由这种基本模式构建的。

完整的编程系统

由于我们在Pi上运行完整的Realtalk系统,并且我们可以在那里远程运行页面代码,我们现在可以在页面上对Pi执行任何操作:我们可以控制任何外设并进行任何计算。机器人、乐器、旋钮/按钮、环境传感器、触摸板 – 我们可以在桌面上编程​​所有这些。我们可以在桌子上为所有的这些编程。

它不像Pi上存在的固定服务,我们只限于一些预设命令来告诉它该做什么。它让我想起了打印机、NeWSeBPF中的PostScript,甚至现代Web本身:不是制作一些动力不足的命令语言,所以A可以控制B,让A将程序发送给B,B在B端执行。然后A(桌子上的页面)可以使用B(Pi)的全部功能。

意见

在更深层次上,在单个统一接口上构建所有资源可以简化互操作性。一旦资源导出9P接口,它就可以透明地与系统的任何其他部分组合,以构建非同寻常的应用程序; 细节是隐藏的。

  • Realtalk是网络透明的。无论是来自本地Realtalk实例还是来自远程Realtalk实例,语句都是相同的。
    • 最终,我们希望在Realtalk实例之间自动共享语句,因此您根本不需要明确地联合它们。想象一下所有Realtalk联合在一起的世界。
    • 你可以从Pi透明地访问回桌子,进行计算、交互和调试; 相反,在你为Arduino之类地东西编程时,它与你的笔记本电脑交互并输出运算结果通常需要额外的工作。
  • 每个Pi只是一个外围设备(peripheral)。Pi不持有任何代码或持久状态。事实上,我在它们地SD卡中烧录的是同一个镜像。

所有实际行为都存在于我手中的页面上,而不在Pi内,这意味着任何人都可以理解并编辑它,就像Dynamicland中的任何其他内容一样。
任何人都可以进入并添加更多传感器和执行器(如果他们有Pi),无需插入天花板或修改“系统软件”。
我几乎认为Pi之于Dynamicland相当于USB端口之于我地笔记本电脑。它是我将东西接入Dynamicland的方式。

  • 这个例子代码不多。Arduino的平台扩展了对物理计算的访问,超越传统的“嵌入式程序员。” Dynamicland中的Pi可以走得更远; 代码可以像Arduino的草图一样简洁明了,而且构建过程更轻巧,更连续,因为你无需连接到笔记本电脑或IDE上。
  • 在桌面上可以轻易运行多个程序/Pi,通过指向来切换它们。这种桌子支持多人并发做游戏。很多人可以同时尝试很多想法。你只需拿出你的旧页面即可切换回旧程序或添加调试视图。

真的,我根本不是为树莓派编程; 我正在为房间编程,而树莓派已成为房间的一种功能。我没有放弃Dynamicland模型的任何强大功能。所有代码仍在桌面上。

未来的暗示

我相信树莓派暗示了Dynamicland的未来。

说实话,我开始这个项目是因为我厌倦了在天花板上移动大型Realtalk投影机–摄像头系统,它们会造成中断。我想玩单独的页面无法实现的交互: 移动真实物体、精确定位、直接触摸页面…… Pi为我们提供了逐步添加新交互的途径。

鉴于这些Pi作为接口计算机,你还可以插入各种传感器并基于它们进行计算(例如,作为科学家或教师)。你在工作台上对现实世界进行测量,并连续分析这些测量结果,而不是要求您从实验室仪器切换到笔记本电脑。我们希望Dynamicland成为一种有利于跟踪而不是模拟现实世界的媒介,而Pi是支持该系统的传感器的平台。

最后,正如我在介绍中所说,Pi暗示我们如何从单机“Realtalk系统”过渡到Realtalk主机的分布式生态系统。Dynamicland并不意味着拥有一台运行整个房间的服务器软件; 它意味着是一台由小型计算机组成的计算机,所有计算机都通过通用协议相互通信。

我们试图找出正确的协议和抽象来使这个生态系统发挥作用,以及正确的价值观和界面范式,使其增强人类而不是疏远人类。

如果你想继续听听这些想法,你可以在Twitter上关注我@rsnous@Fynamicland1。你可能还想阅读我之前关于Geokit地图框架的帖子。

参考