文章目录
前言
本文介绍在 ubuntu 20.04 中安装 Franka Control Interface (FCI),前提为已安装好 ROS Noetic,参考文档如下:
- Franka 官方文档
- @耗纸, 机器人控制该怎么入门?
- David Augustat, How to Compile and Install the Linux Kernel on Ubuntu
- 代码先锋网, ubuntu打实时内核补丁教程以及安装后显卡驱动问题解决方法
- 如何删除内核
一、安装 libfranka 和 franka_ros
安装好 ROS Noetic 后,执行:
sudo apt install ros-noetic-libfranka ros-noetic-franka-ros
从源代码构建之前,卸载 libfranka
和 franka_ros
的现有安装,以避免冲突:
sudo apt remove "*libfranka*"
从Ubuntu的包管理器安装以下依赖项以构建 libfranka:
sudo apt install build-essential cmake git libpoco-dev libeigen3-dev
从 GitHub 下载 libfranka
源代码:
- 对于 Panda:
git clone --recursive https://github.com/frankaemika/libfranka # only for panda
cd libfranka
- 对于 Franka Research 3:
git clone --recursive https://github.com/frankaemika/libfranka --branch 0.10.0 # only for FR3
cd libfranka
在源目录中,创建一个生成目录并运行 CMake:
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=OFF ..
cmake --build .
可选(但推荐)在同一目录中构建 libfranka-Debian 包并安装:
cpack -G DEB
sudo dpkg -i libfranka*.deb
在选择的目录中创建 Catkin 工作区:
cd /path/to/desired/folder
mkdir -p catkin_ws/src
cd catkin_ws
source /opt/ros/noetic/setup.sh
catkin_init_workspace src
然后从 GitHub 下载 franka_ros
存储库:
git clone --recursive https://github.com/frankaemika/franka_ros src/franka_ros
安装任何丢失的依赖项并生成包:
rosdep install --from-paths src --ignore-src --rosdistro noetic -y --skip-keys libfranka
catkin_make -DCMAKE_BUILD_TYPE=Release -DFranka_DIR:PATH=/path/to/libfranka/build
source devel/setup.sh
二、设置实时内核
1. 安装依赖
首先安装编译所需的几个软件包:
sudo apt install build-essential libncurses-dev bison flex libssl-dev libelf-dev fakeroot
安装 dwarves 软件包:
sudo apt install dwarves
接下来从官方网站 kernel.org 下载内核源代码,选择最新的 longterm
版本并复制 tarball
链接,用该链接下载内核源代码并将其解压缩:
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.1.53.tar.xz
tar -xf linux-6.1.53.tar.xz
2. 编译内核
进入Linux源的目录:
cd linux-6.1.53
复制当前安装的 Linux 内核的配置文件:
cp -v /boot/config-$(uname -r) .config
这个配置文件包含了大量不必要的驱动程序和内核模块。可以使用 localmodconfig
命令查看系统中已加载的内核模块,并修改该文件,以便在构建中只包含这些模块。运行该命令时,有任何请求提示,只需每次点击回车键(不键入答案)。
make localmodconfig
接下来,通过运行以下命令对配置进行四次修改:
scripts/config --disable SYSTEM_TRUSTED_KEYS
scripts/config --disable SYSTEM_REVOCATION_KEYS
scripts/config --set-str CONFIG_SYSTEM_TRUSTED_KEYS ""
scripts/config --set-str CONFIG_SYSTEM_REVOCATION_KEYS ""
运行以下命令编译内核:
fakeroot make
或者,8 表示 CPU 核的数量:
fakeroot make -j8
构建完成后通过运行以下命令以检查编译是否成功。返回 0 表示成功,返回其他任何值都不成功:
echo $?
3. 安装内核
首先安装内核模块:
sudo make modules_install
然后安装内核:
sudo make install
最后重启:
sudo reboot
4. 验证内核
通过以下命令检查安装的内核的版本:
uname -rs
返回值与下载的内核源版本相匹配,那么您安装是成功的:
Linux 6.1.53
三、在实时内核下安装显卡驱动
安装完实时内核并重启后,在终端中输入 nvidia-smi
没有弹出显卡驱动信息,这是因为实时内核下的显卡驱动掉了。切换回原来的内核版本,发现是有显卡驱动信息的。在实时内核下,无法直接下载显卡驱动,所以该节介绍怎么在实时内核下安装显卡驱动。
1. 切换回之前的内核
去nvidia官网下载适配自己电脑显卡版本的驱动 (.run 文件),以 GeForce RTX 3070 Laptop GPU
为例,显卡驱动的版本为 535.104.05
。首先安装 dkms
管理工具:
sudo apt install dkms
禁用 nouveau:
sudo gedit /etc/modprobe.d/blacklist.conf
在文件中最后一行插入:
blacklist nouveau
options nouveau modeset=0
保存退出,在终端中输入以下命令,使设置生效并重启:
sudo update-initramfs -u
sudo reboot
通过以下命令验证:
lsmod | grep nouveau
回车无任何反应,则表示成功。
卸载之前的显卡驱动:
sudo apt-get remove --purge nvidia*
在下载目录下运行显卡驱动安装包:
chmod +x NVIDIA-Linux-x86_64-535.104.05.run
sudo ./NVIDIA-Linux-x86_64-535.104.05.run
弹出第一个有关 dkms
的界面选择 yes,其它的都选 no. 安装完成后,重启,打开终端,输入查看显卡信息:
nvidia-smi
2. 切换至实时内核
通过以下 .sh 脚本实时内核下安装显卡驱动:
#!/bin/bash
BUILD_BASE=`pwd`
NV_FILE="NVIDIA-Linux-x86_64-xxx.run" # 这里改成自己下载的.run文件名(之前安装过的)
#NV_URL="https://us.download.nvidia.cn/XFree86/Linux-x86_64/430.50/${NV_FILE}" # 之前已经下好了显卡驱动.run文件,就不用从网上下载了,直接注释掉,而且如果要下载的话,则慢
NEED_TO_COMPILE_NV_KO=1
function clean_env() {
[ -d ./${NV_DIR} ] && rm -rf ./${NV_DIR}
}
function check_env() {
# check if in rt kernel
uname -r | grep rt 1>/dev/null 2>&1
if [ $? -ne 0 ]
then
echo "Not in rt kernel, Please install apollo kernel and reboot machine first."
exit 2
fi
# check if nv ko already in kernel
if [ ! -f /lib/modules/`uname -r`/kernel/drivers/video/nvidia.ko ]
then
export NEED_TO_COMPILE_NV_KO=1
fi
}
function prepare_nv() {
## download nv install file from nvidia home page
#if [ ! -f ./${NV_FILE} ]
#then
# echo "Downloading ${NV_FILE} from nvidia website..."
# wget ${NV_URL} -O ${NV_FILE}
# if [ $? -ne 0 ]
# then
# echo "Downloading ${NV_FILE} failed, please check your network connection!"
# rm -rf ./${NV_FILE}
# exit 1
# fi
#fi
###########上面是下载驱动的代码,我们已经提前下载好了,就不需要这段代码了,直接注释掉############
# +x
chmod +x ./${NV_FILE}
echo "Extracting nvidia install run file..."
./${NV_FILE} -x 1>/dev/null 2>&1
NV_DIR="`echo ${NV_FILE} | awk -F '.run' '{print $1}'`"
NV_VERSION="`echo ${NV_FILE} | awk -F '-' '{print $4}' | awk -F '.run' '{print $1}'`"
export NV_DIR
export NV_VERSION
export NVIDIA_SOURCE="${NV_DIR}/kernel"
}
function install_lib() {
NV_LIB_OUTPUT_PATH="/usr/lib/x86_64-linux-gnu/"
NV_BIN_OUTPUT_PATH="/usr/bin/"
[ -f ./${NV_DIR}/libnvidia-ml.so.${NV_VERSION} ] && /bin/cp -f ./${NV_DIR}/libnvidia-ml.so.${NV_VERSION} ${NV_LIB_OUTPUT_PATH}
[ -f ./${NV_DIR}/libnvidia-fatbinaryloader.so.${NV_VERSION} ] && /bin/cp -f ./${NV_DIR}/libnvidia-fatbinaryloader.so.${NV_VERSION} ${NV_LIB_OUTPUT_PATH}
[ -f ./${NV_DIR}/libnvidia-ptxjitcompiler.so.${NV_VERSION} ] && /bin/cp -f ./${NV_DIR}/libnvidia-ptxjitcompiler.so.${NV_VERSION} ${NV_LIB_OUTPUT_PATH}
[ -f ./${NV_DIR}/libcuda.so.${NV_VERSION} ] && /bin/cp -f ./${NV_DIR}/libcuda.so.${NV_VERSION} ${NV_LIB_OUTPUT_PATH}
[ -f ./${NV_DIR}/nvidia-modprobe ] && /bin/cp -f ./${NV_DIR}/nvidia-modprobe ${NV_BIN_OUTPUT_PATH}
[ -f ./${NV_DIR}/nvidia-smi ] && /bin/cp -f ./${NV_DIR}/nvidia-smi ${NV_BIN_OUTPUT_PATH}
chmod +x /usr/bin/nvidia*
chmod +s /usr/bin/nvidia-modprobe
# link for nvidia
/bin/rm -rf /usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1 /usr/lib/x86_64-linux-gnu/libnvidia-ml.so
/bin/ln -s /usr/lib/x86_64-linux-gnu/libnvidia-ml.so.${NV_VERSION} /usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1
/bin/ln -s /usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1 /usr/lib/x86_64-linux-gnu/libnvidia-ml.so
/bin/rm -rf /usr/lib/x86_64-linux-gnu/libcuda.so /usr/lib/x86_64-linux-gnu/libcuda.so.1
/bin/ln -s /usr/lib/x86_64-linux-gnu/libcuda.so.${NV_VERSION} /usr/lib/x86_64-linux-gnu/libcuda.so.1
/bin/ln -s /usr/lib/x86_64-linux-gnu/libcuda.so.1 /usr/lib/x86_64-linux-gnu/libcuda.so
# take effect
/sbin/ldconfig 1>/dev/null 2>&1
}
function build_nv() {
if [ ${NEED_TO_COMPILE_NV_KO} == 0 ]
then
return
fi
NVIDIA_MOD_REL_PATH='kernel/drivers/video'
NVIDIA_OUTPUT_PATH="/lib/modules/`uname -r`/${NVIDIA_MOD_REL_PATH}"
CPUNUM=`cat /proc/cpuinfo | grep processor | wc | awk -F " " '{print $1}'`
export IGNORE_PREEMPT_RT_PRESENCE=true
cd ${NVIDIA_SOURCE} && make -j ${CPUNUM} module
cd ${BUILD_BASE}
unset IGNORE_PREEMPT_RT_PRESENCE
mkdir -p ${NVIDIA_OUTPUT_PATH}
[ -f ${NVIDIA_SOURCE}/nvidia.ko ] && cp ${NVIDIA_SOURCE}/nvidia.ko ${NVIDIA_OUTPUT_PATH}
[ -f ${NVIDIA_SOURCE}/nvidia-modeset.ko ] && cp ${NVIDIA_SOURCE}/nvidia-modeset.ko ${NVIDIA_OUTPUT_PATH}
[ -f ${NVIDIA_SOURCE}/nvidia-drm.ko ] && cp ${NVIDIA_SOURCE}/nvidia-drm.ko ${NVIDIA_OUTPUT_PATH}
[ -f ${NVIDIA_SOURCE}/nvidia-uvm.ko ] && cp ${NVIDIA_SOURCE}/nvidia-uvm.ko ${NVIDIA_OUTPUT_PATH}
depmod -a
}
# check environment
check_env
# prepare for nvidia
prepare_nv
# build nvidia.ko
build_nv
# install user lib
install_lib
# clean environment
clean_env
echo "Done to install nvidia kernel driver and user libraries."
运行以下命令,将以上脚本代码复制粘贴进去。对相应内容按自己的显卡驱动安装包的版本修改,修改部分在上面注明了:
sudo gedit install_nvidia.sh
注意: 使用以下命令查看内核版本,版本号包含 PREEMPT_DYNAMIC
,则需要注释掉脚本中的这些内容:
uname -a
uname -r | grep rt 1>/dev/null 2>&1
if [ $? -ne 0 ]
then
echo "Not in rt kernel, Please install apollo kernel and reboot machine first."
exit 2
fi
修改后,运行:
chmod +x install_nvidia.sh
sudo ./install_nvidia.sh
安装完成后重启。
输入查看显卡信息,出现显卡驱动信息,说明安装成功:
nvidia-smi
3. 允许用户为其进程设置实时权限
添加一个名为 realtime
的组,并将控制机器人的用户添加到此组中:
sudo addgroup realtime
sudo usermod -a -G realtime $(whoami)
将以下限制添加到 /etc/security/limits.conf
中,重启后生效:
@realtime soft rtprio 99
@realtime soft priority 99
@realtime soft memlock 102400
@realtime hard rtprio 99
@realtime hard priority 99
@realtime hard memlock 102400