小米杯 Docker 容器内 LCM 环境搭建教程
本教程将引导您在基于 Ubuntu 的 Docker 容器中搭建 LCM(Lightweight Communications and Marshalling)环境,解决在配置过程中可能遇到的常见网络和依赖问题。
前置条件:
- 已安装 Docker 的 Linux 宿主机(本例为 Ubuntu 虚拟机)。
- 可访问互联网的宿主机网络连接。
- 已构建名为
cyberdog_sim:v2
的 Docker 镜像。 - 熟悉 Linux 命令行操作。
教程步骤:
第一部分:宿主机网络环境准备 (关键)
在启动 Docker 容器之前,必须确保宿主机(本例中的 Ubuntu 虚拟机)能够正常访问互联网。之前遇到的 Temporary failure resolving
错误通常是宿主机网络问题导致的。
检查宿主机网络连接:
在宿主机终端 (c@c-virtual-machine:~ $ 或 root@c-virtual-machine:/#) 执行:
Bash
1
2ping 8.8.8.8
ping google.com- 如果两者都成功(无
100% packet loss
或网络不可达
),则宿主机网络正常。 - 如果失败,请检查虚拟机的网络设置(如 VMware/VirtualBox 的网络适配器模式,推荐 NAT 模式),并尝试重启虚拟机以重新获取 IP 地址。
- 确保宿主机的网卡(例如
ens33
)已分配 IPv4 地址(如192.168.130.132
),可以通过ip a
命令查看。
- 如果两者都成功(无
(可选但推荐)宿主机 auto_lcm_init.sh 脚本的适应性修改:
尽管此脚本主要用于容器内部,但如果将来你需要在宿主机直接运行与 LCM 相关的工具,提前修改会避免同样的问题。
打开宿主机上的脚本文件:
nano /home/xiangao/motion/scripts/auto_lcm_init.sh
找到获取接口名称的行:
enxname=$(ifconfig | grep -B 1 -E '192.168.55.100|192.168.44.100' | grep 'flags' | cut -d ':' -f1)
将其中的 IP 地址替换为你的宿主机实际获取到的 IP 地址(例如 192.168.130.132):
enxname=$(ifconfig | grep -B 1 -E '192.168.130.132' | grep 'flags' | cut -d ':' -f1)
保存并退出。
第二部分:启动 Docker 容器 (必须使用 --network host
)
正确启动容器是让容器访问宿主机网络的关键。
停止并删除所有旧的 Docker 容器实例:
在宿主机终端执行:
Bash
1
2
3sudo docker ps -a # 找到 cyberdog_sim:v2 容器的 CONTAINER ID 或 NAMES
sudo docker stop <CONTAINER_ID_或_NAME> # 如果容器正在运行
sudo docker rm <CONTAINER_ID_或_NAME> # 删除容器以宿主机网络模式启动 Docker 容器:
在宿主机终端执行,确保包含 --network host 标志:
Bash
1
sudo docker run -it --network host --shm-size="1g" --privileged=true -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix cyberdog_sim:v2
这会让你进入容器的 shell 环境 (
root@c-virtual-machine:/#
或类似)。在容器内部验证网络接口:
进入容器后,立即执行 ip a。
Bash
1
ip a
验证: 你应该能看到宿主机的网络接口,特别是
ens33
,并且它的 IP 地址与宿主机上的ens33
IP(如192.168.130.132
)一致。如果看到eth0
和172.17.0.x
,说明--network host
未生效,需要重新检查启动命令。
第三部分:容器内 LCM 相关依赖和脚本执行
容器成功启动并连接到宿主机网络后,可以在容器内部安装缺失的软件包并执行 LCM 初始化脚本。
在容器内部更新软件包列表并安装必要的网络工具:
虽然 net-tools 可能已存在,但 iproute2 是现代 Linux 系统中 ip 命令的提供者,对网络操作至关重要。
Bash
1
2apt-get update
apt-get install -y iproute2 net-tools- 排查: 如果
apt-get update
仍出现Temporary failure resolving
,请返回第一部分,宿主机网络未完全恢复。
- 排查: 如果
在容器内部编辑 auto_lcm_init.sh 脚本:
此脚本用于配置 LCM 所需的组播网络接口。它的 IP 匹配规则需要与容器当前识别的 ens33 接口的 IP 地址一致。
进入脚本所在目录:
cd /home/xiangao/motion/scripts
打开脚本文件:
nano auto_lcm_init.sh
找到获取接口名称的行:
enxname=$(ifconfig | grep -B 1 -E '192.168.55.100|192.168.44.100' | grep 'flags' | cut -d ':' -f1)
将其中的 IP 地址替换为容器内部 ip a 显示的 ens33 的实际 IP 地址(例如 192.168.130.132):
enxname=$(ifconfig | grep -B 1 -E '192.168.130.132' | grep 'flags' | cut -d ':' -f1)
保存并退出
nano
。
在容器内部执行
auto_lcm_init.sh
脚本:Bash
1
2chmod +x auto_lcm_init.sh
./auto_lcm_init.sh- 验证: 脚本执行后不应有任何错误输出,或只有成功信息。如果报错
Device not found
或SIOCADDRT: No such device
,请重新检查enxname
变量是否正确获取到接口名称,以及iproute2
和net-tools
是否完整安装。
- 验证: 脚本执行后不应有任何错误输出,或只有成功信息。如果报错
第四部分:解决 Python 模块依赖问题
motion.py
脚本依赖多个 Python 模块(如 lcm
、 rclpy
、 pyzbar
、 toml
)。它们需要单独安装。
安装 Python 的
pip
工具:Bash
1
2apt-get update # 再次更新以防万一
apt-get install -y python3-pip安装
lcm
的 Python 绑定:Bash
1
pip3 install lcm
- 注意: 如果
pip3
无法找到lcm
,可能需要尝试apt-get install -y python3-lcm
。
- 注意: 如果
Source ROS 2 环境 (解决 ModuleNotFoundError: No module named 'rclpy'):
rclpy 是 ROS 2 的核心 Python 库。为了让 Python 找到它,需要加载 ROS 2 的环境变量。
Bash
1
source /opt/ros/galactic/setup.bash # 根据你的ROS 2版本调整,如foxy, humble等
- 验证:
python3 -c "import rclpy; print('rclpy imported successfully')"
- 验证:
安装 pyzbar 库及其依赖 (解决 ModuleNotFoundError: No module named 'pyzbar' 和 Unable to find zbar shared library):
pyzbar 需要底层的 zbar 共享库。
Bash
1
2
3
4apt-get update
apt-get install -y --reinstall libzbar0 zbar-tools # 强制重新安装 zbar 库
ldconfig # 更新动态链接库缓存
pip3 install --upgrade --force-reinstall pyzbar # 重新安装 pyzbar Python 绑定安装
toml
模块 (解决ModuleNotFoundError: No module named 'toml'
):Bash
1
pip3 install toml
第五部分:运行您的应用程序
所有依赖都安装并配置好后,现在可以尝试运行您的主程序了。
在容器内,回到
motion.py
脚本所在的目录:Bash
1
cd /home/xiangao/motion
运行
motion.py
:Bash
1
python3 motion.py
- 预期: 程序应该能成功导入所有模块并开始执行。如果遇到新的
ModuleNotFoundError
,请重复安装对应模块的步骤。如果遇到运行时错误,则需要根据错误信息进行程序逻辑或环境的其他调试。
- 预期: 程序应该能成功导入所有模块并开始执行。如果遇到新的
通过遵循这些步骤,您应该能够成功地在 Docker 容器内的虚拟环境中搭建 LCM 并运行依赖它的 Python 应用程序。整个过程的核心在于理解 Docker 容器的网络模式,以及如何识别并安装所有必要的系统和 Python 依赖。