Files
2026-10-16 17:27:30 +08:00

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 "$@"