首先说下我要达到的目的:

使用Mac主机上的Docker容器(Ubuntu)调用树莓派连接的摄像头,并在Mac主机上显示出来。

分步实现:

  1. 在Mac主机的某一个Docker容器运行GUI

Docker相当于一个不带外设的主机,只运行一个操作系统OS,可以想像成是一台Mac Pro。想要用Docker来显示图形化界面(GUI),就必须借用主机(这里是Mac)的显示器(Display)。具体操作方法见下面两个网站,关于Docker如何借用主机的显示器以及背后数据传输的路径,在英文视频里有讲解。

https://cntnr.io/running-guis-with-docker-on-mac-os-x-a14df6a76efc 英文版本带视频

最终要实现:在Docker里运行Xeyes,能在桌面上弹出一个窗口,是一双跟着鼠标运动的眼睛。




docker容器内运行服务 docker运行gui_Mac


Troubleshooting


> socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:"$DISPLAY“
2020/03/02 21:02:49 socat[8005] E connect(5, LEN=68 AF=1 "/private/tmp/com.apple.launchd.watxgWtj7k/org.macosforge.xquartz:0", 68): Connection refused


--> 重装Xquartz,推荐使用home brew安装,参照第一步的两个网址。装好Xquartz之后可以在主机的终端里敲入echo $DISPLAY,如果返回值长得像这样就说明Xquartz装好了:


> echo $DISPLAY
/private/tmp/com.apple.launchd.nzm51qjuIW/org.macosforge.xquartz:0


别忘了修改Xquartz的设置,勾选“允许从网络客户端接入”。配置完Xquartz之后,一定要登出Mac,即点击屏幕左上角苹果标志,然后选择“登出登陆xxx”,再重新输密码打开Mac,才能成功运行。

2. 在我配置好的Ubuntu系统里运行GUI

我尝试在Ubuntu里运行xarclock ,这是一个X程序,用于在桌面上显示一个时钟(一开始我没有装过xarclock这个package,耐心等待一下,Ubuntu会自动安装这个pkg)。最终要实现:在Docker Ubuntu里运行xarclock,能在桌面上弹出一个窗口,是一个实时跳动的时钟。

Troubleshooting


> root@c224904495dd:/# rqt_image_view
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
QXcbConnection: Could not connect to display 
Could not connect to any X display.


如果第一步成功了,但这一步报出Could not connect to any X display错误,应该是环境变量未修改。每次重新运行docker上的操作系统的时候,都需要加载一下环境变量,代码如下:


export DISPLAY=192.168.xx.xx:0


3. 使用Docker Ubuntu调用树莓派摄像头

3.1 树莓派运行摄像头驱动

3.2 Ubuntu里运行rqt_image_view

Troubleshooting

Docker端


> rqt_image_view
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
QXcbConnection: Could not connect to display 192.168.1.7:0
Could not connect to any X display.


主机端


> socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:"$DISPLAY“
2020/03/02 21:58:07 socat[8752] E read(6, 0x7fe376800000, 8192): Operation timed out


同时出现这两个错误,是因为我需要把Mac和树莓派连到同一个路由器的网络下面,这时候Mac的ip发生了改变,所以需要重新修改环境变量为Mac的新ip


export DISPLAY=192.168.xx.xx:0


ps. 查看Mac ip地址的命令是


ifconfig en0



下面是废话:

当你发现一个问题,比起解决问题本身,可能最困难的部分往往是不知道怎么提问。计算机相关的知识,只要提对了问题,互联网基本上就能给你找到正确的答案。互联网最大的好处之一就是,信息足够多,总会有人碰到一样的问题然后发出来。
互联网会教给你,但不保证教会你,更不能保证教给你的都是对的。千差万别的前提,会导致你在参考的时候无所适从。我可能浏览了数十个网站,才能找到我想要找的问题,也才有了这篇文字。
这个时候要做的,就是反复对比,反复浏览,反复尝试,永不放弃。每一次走弯路,都让我对docker,对操作系统的运作有了更深的认识。而且我发现,最终可靠的还是英文,不必畏惧外语带来的障碍,代码部分是一样的,文字部分用语都是非常简易的口语,你只要开始阅读,就发现一切并不难懂,问题不会出在语言上。更甚,国内很多博客就是在抄袭英文的,在抄袭过程中又不负责任地篡改了一些信息,或者因为翻译的低劣形成误导。结合中英文一起阅读,可能比仅仅中文搜索,更快接近问题和答案。
最后,不要忘了First Principle,永远记得最初的问题是什么,随时check自己是否在解决最初的那个问题,而不是纠结在其他的问题或者细枝末节。