100 lines
3.8 KiB
Bash
Executable File
100 lines
3.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Orisys 通止规工位桌面程序(窗口,不是网页)。
|
|
#
|
|
# bash ~/桌面/orisys_arm/station/run_station.sh
|
|
|
|
set -eo pipefail
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
case "${1:-}" in
|
|
-h|--help)
|
|
echo "用法:bash station/run_station.sh [--offline | --self-test]"
|
|
echo "默认启动工位和独立后端;--offline 禁止设备访问;--self-test 运行离线回归。"
|
|
exit 0
|
|
;;
|
|
esac
|
|
# 这份搬迁的 symlink-install 在 /tmp/orisys_mnt 构建;只在私有挂载空间恢复它,
|
|
# 否则工位虽然能开,ROS 消息和相机桥的安装链接却失效。
|
|
_arm_hook="${ROOT}/install/arm_msgs/share/arm_msgs/local_setup.bash"
|
|
if [[ "${ROOT}" != /tmp/orisys_mnt && -L "${_arm_hook}" && ! -e "${_arm_hook}" && "$(readlink "${_arm_hook}")" == /tmp/orisys_mnt/* ]]; then
|
|
exec unshare -rm bash -c '
|
|
set -e
|
|
mkdir -p /tmp/orisys_mnt
|
|
mount --bind "$1" /tmp/orisys_mnt
|
|
shift
|
|
exec bash /tmp/orisys_mnt/station/run_station.sh "$@"
|
|
' bash "${ROOT}" "$@"
|
|
fi
|
|
unset _arm_hook
|
|
export XDG_CACHE_HOME="${XDG_CACHE_HOME:-${HOME}/.cache}"
|
|
# shellcheck disable=SC1091
|
|
source "${ROOT}/scripts/env.sh"
|
|
# 源码在最前。conda 的 site-packages 要排在 Humble 的 python3.10 之前,
|
|
# 否则 3.11 的解释器会去加载 cpython-310 的 rclpy,相机预览线程直接失败。
|
|
_conda_site=""
|
|
if [[ -n "${CONDA_PREFIX:-}" ]]; then
|
|
_py_mm="$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')"
|
|
if [[ -d "${CONDA_PREFIX}/lib/python${_py_mm}/site-packages" ]]; then
|
|
_conda_site="${CONDA_PREFIX}/lib/python${_py_mm}/site-packages"
|
|
fi
|
|
fi
|
|
export PYTHONPATH="${ROOT}/station/src:${ROOT}/src/arm_application${_conda_site:+:${_conda_site}}${PYTHONPATH:+:${PYTHONPATH}}"
|
|
unset _conda_site _py_mm
|
|
# 屏幕跟当前登录会话走。这台工控机是 :1,别的 Linux 桌面常常是 :0。
|
|
if [[ -n "${DISPLAY:-}" ]]; then
|
|
_disp="${DISPLAY#:}"
|
|
_disp="${_disp%%.*}"
|
|
if [[ ! -S "/tmp/.X11-unix/X${_disp}" ]]; then
|
|
unset DISPLAY
|
|
fi
|
|
unset _disp
|
|
fi
|
|
if [[ -z "${DISPLAY:-}" ]]; then
|
|
_seat="$(who | awk -v u="$(id -un)" '$1==u && $2 ~ /^:/ {print $2; exit}')"
|
|
_seat="${_seat%%.*}"
|
|
_n="${_seat#:}"
|
|
if [[ -n "${_n}" && -S "/tmp/.X11-unix/X${_n}" ]]; then
|
|
export DISPLAY="${_seat}"
|
|
else
|
|
for _sock in /tmp/.X11-unix/X*; do
|
|
if [[ -S "${_sock}" ]]; then
|
|
export DISPLAY=":${_sock##*/X}"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
unset _seat _n _sock
|
|
fi
|
|
# 有真实屏幕时不要留在 offscreen,否则 OpenGL 窗口起不来,模型也不会画到显卡上。
|
|
if [[ "${QT_QPA_PLATFORM:-}" == "offscreen" && -n "${DISPLAY:-}" ]]; then
|
|
_disp="${DISPLAY#:}"
|
|
_disp="${_disp%%.*}"
|
|
if [[ -S "/tmp/.X11-unix/X${_disp}" ]]; then
|
|
unset QT_QPA_PLATFORM
|
|
fi
|
|
unset _disp
|
|
fi
|
|
if [[ -z "${XAUTHORITY:-}" ]]; then
|
|
if [[ -r "${HOME}/.Xauthority" ]]; then
|
|
export XAUTHORITY="${HOME}/.Xauthority"
|
|
elif [[ -r "/run/user/$(id -u)/gdm/Xauthority" ]]; then
|
|
export XAUTHORITY="/run/user/$(id -u)/gdm/Xauthority"
|
|
fi
|
|
fi
|
|
# Qt 6.5 起 xcb 插件依赖 libxcb-cursor。系统没装这个包时,用用户目录里单独放的那一份,
|
|
# 不要把整个 conda lib 塞进 LD_LIBRARY_PATH(会和系统的 glib/pango 撞符号)。
|
|
_cursor_dir="${HOME}/.local/lib/xcb-cursor"
|
|
if [[ ! -e /usr/lib/x86_64-linux-gnu/libxcb-cursor.so.0 && -e "${_cursor_dir}/libxcb-cursor.so.0" ]]; then
|
|
export LD_LIBRARY_PATH="${_cursor_dir}${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
|
|
fi
|
|
unset _cursor_dir
|
|
# 工位单独固定 Qt 绑定版本,不修改 ROS/conda 内的包。
|
|
source "${ROOT}/scripts/lib/qt_env.sh"
|
|
orisys_qt_env
|
|
|
|
if [[ "${1:-}" == "--self-test" ]]; then
|
|
export QT_QPA_PLATFORM=offscreen
|
|
exec python3 -m unittest discover -s "${ROOT}/station/test" -v
|
|
fi
|
|
|
|
exec python3 -m station.operator_app "$@"
|