总述
本文主要解决在OpenNAO虚拟机中成功运行NAOqi Python SDK的问题,以便不依赖实体机器人成进行测试与代码编译工作。
因为我们的AXMService代码必须在pepper本体中运行,导致需要打包编译的时候,必须找一个机器人来操作,而且编译过程还不能在pepper里面,因为没有root权限,缺乏一些依赖包,只能在NAO的机器系统里面。
这一点大大限制了我们打包部署的过程。所以一直希望,去掉这个硬件依赖,让我们直接在电脑的虚拟里面就能打包。
下面先重现在OpenNAO中运行代码遇到的报错,然后给出相应的解决办法。
整个步骤完成后的OpenNAO系统,我已经通过VirtuaBox导出了一个镜像系统文件,放到公司的共享上面,文件名为 opennao-vm-2.1.2.17-axm0311.ova
以后大家具体使用,直接导入我制作好的系统镜像,然后直接使用,并不需要进行以下这些步骤。
问题重现
安装好 pynaoqi-python2.7-2.4.3.28-linux32
wget -c https://community-static.aldebaran.com/resources/2.4.3.28/sdk-python/pynaoqi-python2.7-2.4.3.28-linux32.tar.gz tar vxzf pynaoqi-python2.7-2.4.3.28-linux32.tar.gz rm pynaoqi-python2.7-2.4.3.28-linux32.tar.gz export PYTHONPATH=/home/nao/pynaoqi-python2.7-2.4.3.28-linux32/ export LD_LIBRARY_PATH=/home/nao/.local/AXMService/lib:/home/nao/.local/lib:/home/nao/pynaoqi-python2.7-2.4.3.28-linux32/
测试naoqi sdk是否能正常运行,只需要打开python shell,尝试import qi:
virtual-nao [err 1] ~/.local/AXMService $ python Python 2.7.8 (default, Sep 10 2014, 15:09:52) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import qi Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/nao/pynaoqi-python2.7-2.4.3.28-linux32/qi/__init__.py", line 66, in <module> from _qi import Application as _Application ImportError: /usr/lib/gcc/i686-pc-linux-gnu/4.5.3/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by /home/nao/pynaoqi-python2.7-2.4.3.28-linux32/libqi.so)
这个错原因为gcc版本太低,naoqi sdk用的较高版本的gcc编译的,本系统没有对应的高版本库,解决办法为升级gcc,见下面。
解决gcc版本问题后继续。
virtual-nao [0] ~/gcc-4.8.5/build $ python Python 2.7.8 (default, Sep 10 2014, 15:09:52) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import qi Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/nao/pynaoqi-python2.7-2.4.3.28-linux32/qi/__init__.py", line 66, in <module> from _qi import Application as _Application ImportError: /lib/libc.so.6: version `GLIBC_2.15' not found (required by /home/nao/pynaoqi-python2.7-2.4.3.28-linux32/libqi.so)
这个错误原因为glibc库版本太低,升级glibc到2.15后解决,步骤见下面。
解决glibc版本后继续。需要把安装路径加到环境变量中去:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/nao/.local/glibc2.15/lib
这时候再尝试import qi
virtual-nao [0] ~ $ python Python 2.7.8 (default, Sep 10 2014, 15:09:52) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import qi >>>
发现已经没有报错,说明naoqi sdk已经安装好了,下面我们来运行下axmservice看看。
运行 AXMService/run.py 报错:
virtual-nao [0] ~/.local/AXMService $ python run.py Traceback (most recent call last): File "run.py", line 50, in <module> from axmservice.config import ConfigCommon File "/home/nao/.local/AXMService/axmservice/config.py", line 4, in <module> from axmservice.helper.config_helper import ConfigHelper File "/home/nao/.local/AXMService/axmservice/helper/config_helper.py", line 2, in <module> import requests File "/usr/lib/python2.7/site-packages/requests/__init__.py", line 58, in <module> from . import utils File "/usr/lib/python2.7/site-packages/requests/utils.py", line 12, in <module> import cgi File "/usr/lib/python2.7/cgi.py", line 51, in <module> import mimetools File "/usr/lib/python2.7/mimetools.py", line 6, in <module> import tempfile File "/usr/lib/python2.7/tempfile.py", line 34, in <module> from random import Random as _Random File "/usr/lib/python2.7/random.py", line 45, in <module> from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil ImportError: /usr/lib/python2.7/lib-dynload/math.so: undefined symbol: PyFPE_jbuf
需要重新用gcc 编译python 2.8.7,得到新的math.so,见下面步骤。
之后就能顺利运行axmservice的代码:
virtual-nao [0] ~/.local/AXMService $ python run.py [I 170311 13:09:51 functions:59] Start cover config [I 170311 13:09:51 functions:106] cover ConfigASR.use_alitts from False into False [I 170311 13:09:51 functions:106] cover ConfigASR.use_aliasr from False into False [W] 17176 qimessaging.transportsocket: connect: Connection refused Traceback (most recent call last): File "run.py", line 96, in <module> qi_helper.connect() File "/home/nao/.local/AXMService/axmservice/helper/qi_helper.py", line 22, in connect app.start() RuntimeError: System error: Connection refused
这里的 Connection refused 不是因为环境问题,而是本地没有开启naoqi-bin服务,拿不到service。
然后运行pyinstaller尝试编译,就可以成功。
升级gcc到4.8.5
wget -c "http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-4.8.5/gcc-4.8.5.tar.gz" tar vxzf gcc-4.8.5.tar.gz cd gcc-4.8.5 ./contrib/download_prerequisites mkdir build cd build ../configure --prefix=/home/nao/.local/ --enable-checking=release --enable-languages=c,c++ --disable-multilib make make install
编译可能需要几个小时时间,需耐心等待。我用我的Macbook Pro,开了8G内存4核cpu给虚拟机,用 make -j4 火力全开编译,也花了 45 分钟。
参考:https://itbilu.com/linux/management/V1vdnt9ll.html
升级glibc到2.15
wget -c http://ftp.gnu.org/gnu/glibc/glibc-2.15.tar.gz tar vxzf glibc-2.15.tar.gz wget http://ftp.gnu.org/gnu/glibc/glibc-ports-2.15.tar.gz tar vxzf glibc-ports-2.15.tar.gz mv glibc-ports-2.15 glibc-2.15/ports cd glibc-2.15 mkdir build cd build ../configure --prefix=/home/nao/.local/glibc2.15/ --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin CC='gcc -U__i686' make sudo make install
注意这里一定要安装到 .local/glibc2.15 ,不要覆盖系统全局的,不然非常危险,glibc是linux系统非常底层的库,覆盖后连ls等基础的linux命令都会出现 segment fault。
如果上面在configure的时候不加参数 CC=’gcc -U__i686′ ,make的时候会报如下的错:
../sysdeps/i386/fpu/s_frexp.S: Assembler messages: ../sysdeps/i386/fpu/s_frexp.S:66: Error: invalid identifier for ".ifdef" ../sysdeps/i386/fpu/s_frexp.S:66: Error: junk at end of line, first unrecognized character is `1' ../sysdeps/i386/fpu/s_frexp.S:66: Error: junk at end of line, first unrecognized character is `1' ../sysdeps/i386/fpu/s_frexp.S:66: Error: Missing symbol name in directive ../sysdeps/i386/fpu/s_frexp.S:66: Error: junk at end of line, first unrecognized character is `1' ../sysdeps/i386/fpu/s_frexp.S:66: Error: Missing symbol name in directive ../sysdeps/i386/fpu/s_frexp.S:66: Error: junk at end of line, first unrecognized character is `.' ../sysdeps/i386/fpu/s_frexp.S:66: Error: junk at end of line, first unrecognized character is `1' ../sysdeps/i386/fpu/s_frexp.S:66: Error: expected comma after name `' in .size directive ../sysdeps/i386/fpu/s_frexp.S:66: Error: ".endif" without ".if" ../sysdeps/i386/fpu/s_frexp.S:66: Error: junk `.get_pc_thunk.dx' after expression make[2]: *** [/home/nao/glibc-2.15/build/math/s_frexp.os] Error 1 make[2]: *** Waiting for unfinished jobs.... make[2]: Leaving directory `/home/nao/glibc-2.15/math' make[1]: *** [math/subdir_lib] Error 2 make[1]: Leaving directory `/home/nao/glibc-2.15' make: *** [all] Error 2
make install的时候会报错:
/home/nao/glibc-2.15/build/elf/ldconfig \ /home/nao/.local/glibc2.15/lib /home/nao/.local/glibc2.15/lib /home/nao/glibc-2.15/build/elf/ldconfig: Can't open configuration file /home/nao/.local/glibc2.15/etc/ld.so.conf: No such file or directory make[1]: Leaving directory `/home/nao/glibc-2.15'
解决办法:
sudo cp /etc/ld.so.conf /home/nao/.local/glibc2.15/etc/
参考:http://love.junzimu.com/archives/2269
解决 python中math.so的版本问题
下载python 2.7.8,重新编译,得到新的 math.so,覆盖原来的就行了。
重新开一个全新的OpenNAO虚拟机编译python,因为我们只需要math.so,全部编译Python覆盖系统的话,会出现问题,我尝试过。
wget -c https://www.python.org/ftp/python/2.7.8/Python-2.7.8.tgz tar vxzf Python-2.7.8.tgz cd Python-2.7.8 ./configure make sudo make install
把得到的 /usr/lib/python2.7/lib-dynload/math.so 复制到我们的系统中去。
环境变量
需要添加两个环境变量
export LD_LIBRARY_PATH=/home/nao/.local/AXMService/lib:/home/nao/.local/lib:/home/nao/.local/glibc2.15/lib:/home/nao/pynaoqi-python2.7-2.4.3.28-linux32/ export PYTHONPATH=/home/nao/pynaoqi-python2.7-2.4.3.28-linux32/
pyinstaller
在执行pyinstaller的时候,可能会报错,说找不到 ~/.local/bin/lddlibc4 ,这时从系统路径中复制过去即可:
cp /usr/bin/lddlibc4 ~/.local/bin/