Initial import of ORISYS arm workstation

This commit is contained in:
cheng
2026-10-16 17:27:30 +08:00
commit 2b74c50ba8
745 changed files with 1199101 additions and 0 deletions
+136
View File
@@ -0,0 +1,136 @@
#!/usr/bin/env bash
# 真机 Rizon4 启动入口 —— 设置 RDK 运行时库,然后以 backend:=real 启动整栈
# 注意:这里不加 `set -u` —— conda/RoboStack 的钩子会引用未绑定的变量(CONDA_BUILD、COLCON_TRACE)
#
# bash ~/ros2/scripts/run_real.sh
# bash ~/ros2/scripts/run_real.sh --arm 91
# bash ~/ros2/scripts/run_real.sh --sn Rizon4-063991 # 本次启动换臂(不改 yaml)
set -eo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
FLEXIV_PREFIX="${HOME}/flexiv_install"
LIST_ONLY=false
NO_STOP=false
while [[ $# -gt 0 ]]; do
case "$1" in
--sn|--arm) export ROBOT_SN="${2:?}"; export ROBOT_ARM="${2}"; shift 2 ;;
--no-stop) NO_STOP=true; shift ;;
--list|-l) LIST_ONLY=true; shift ;;
-h|--help)
sed -n '2,8p' "$0"
echo " 机械臂模型在工位程序里看,这里默认不开 RViz。"
echo " 其余参数传给 ros2 launch。要临时打开 RViz:use_rviz:=true"
exit 0
;;
*) break ;;
esac
done
# shellcheck disable=SC1091
source "${ROOT}/scripts/lib/dev_tools.sh"
dev_source_conda
conda activate ros_flexiv
if [[ ! -f "${ROOT}/install/setup.bash" ]]; then
echo "ERROR: ${ROOT}/install/setup.bash 不存在。先在仓库根目录 colcon build,不要在中文路径下编。" >&2
exit 1
fi
# shellcheck disable=SC1091
source "${ROOT}/install/setup.bash"
# 本机同时有 /opt/ros/humble。install 会把它排到 conda 前面,
# 3.10 的 ros2 会去加载 ros_flexiv 里 3.11 的 rclpy。把 conda 的 ros2 放回最前。
if [[ -n "${CONDA_PREFIX:-}" && -x "${CONDA_PREFIX}/bin/ros2" ]]; then
export PATH="${CONDA_PREFIX}/bin:${PATH}"
fi
# shellcheck disable=SC1091
source "${ROOT}/scripts/lib/load_site_config.sh"
# 真机与仿真的 DDS 域隔离:这个入口**不经过** env.sh,所以这里也得纠正一次。
# shellcheck source=lib/ros_domain.sh
source "${ROOT}/scripts/lib/ros_domain.sh"
ros_domain_force_real
# `flexiv_hardware` 必须从 flexiv_install 加载 spdlog/RBDyn(不能用 conda 的 fmt v11)
export LD_LIBRARY_PATH="${FLEXIV_PREFIX}/lib:${LD_LIBRARY_PATH:-}"
# `SITE_ROBOT_SN` 是解析后的 Flexiv 序列号(89/91 别名已经映射好了)。
ROBOT_SN="${SITE_ROBOT_SN:?run_real.sh 需要已配置的机械臂 SN —— 见 scripts/lib/load_site_config.sh 的报错}"
ROBOT_IP="${ROBOT_IP:-${SITE_ROBOT_IP:-192.168.100.1}}"
NET_IFACE="${SITE_NET_IFACE:-}"
RDK_PYTHON="$(dev_rdk_python)"
if [[ "${LIST_ONLY}" == true ]]; then
python3 "${ROOT}/scripts/lib/export_site_env.py" --print
exit 0
fi
echo "=== site: ${SITE_CONFIG:-n/a} SN=${ROBOT_SN} ${SITE_ROBOT_LABEL:-} arm=${SITE_ROBOT_ARM:-} ==="
echo "=== catalog: ${SITE_ROBOT_CATALOG:-} ==="
echo "=== handeye: ${SITE_HANDEYE_FILE:-} ==="
echo "=== camera serial: ${SITE_CAM_SERIAL:-} gripper: ${SITE_GRIP_MODEL:-} ${SITE_GRIP_PORT:-} ==="
echo "=== network iface=${NET_IFACE:-auto} robot=${ROBOT_IP} pc=${SITE_PC_IP:-} ==="
if [[ "${NO_STOP}" == true ]]; then
echo "=== --no-stop:不扫 install/(感知和伺服还在,扫了会把自己杀掉)==="
else
echo "=== stop leftover real stack (RDK exclusive) ==="
# 以前这里是两行 pkill(ros2_control_node + stack.launch),漏掉了
# arm_control 那一族**独立存活**的孤儿(adapter / named_pose_server /
# arm_status_node / joint_state_publisher)—— 它们会冒名顶替新一轮的栈,
# 见 lib/real_procs.sh 的文件头。扫描规则与 stop_real.sh 共用一份。
# shellcheck source=lib/real_procs.sh
source "${ROOT}/scripts/lib/real_procs.sh"
mapfile -t _stale < <(real_proc_targets)
if [ "${#_stale[@]}" != "0" ]; then
echo "清掉上一轮残留(${#_stale[@]} 个):"
for _pid in "${_stale[@]}"; do
printf ' %-7s %s\n' "$_pid" "$(ps -o args= -p "$_pid" 2>/dev/null | cut -c1-120)"
kill -TERM "$_pid" 2>/dev/null || true
done
sleep 1
for _pid in "${_stale[@]}"; do
kill -0 "$_pid" 2>/dev/null && kill -KILL "$_pid" 2>/dev/null || true
done
unset _pid
fi
unset _stale
fi
sleep 1
# 清掉把 91 的 .100 误绑到 89 MAC 上的陈旧 ARP
if [[ -n "${NET_IFACE}" ]]; then
ip neigh del "${ROBOT_IP}" dev "${NET_IFACE}" 2>/dev/null || true
fi
if ping -c 2 -W 1 "${ROBOT_IP}" >/dev/null 2>&1; then
echo "robot ${ROBOT_IP} ping OK"
else
echo "WARN: cannot ping ${ROBOT_IP} — 这一台不在网里,RDK 大概率会失败。"
echo " 本机: $(ip -4 -o addr show dev "${NET_IFACE:-enp4s0}" 2>/dev/null | awk '{print $4}' | tr '\n' ' ')"
echo " ARP ${ROBOT_IP}: $(ip neigh show "${ROBOT_IP}" 2>/dev/null | head -1 || echo none)"
MAC91="$(ip neigh show "${ROBOT_IP}" 2>/dev/null | awk '{print $5}' | head -1)"
MAC89="$(ip neigh show 192.168.2.101 2>/dev/null | awk '{print $5}' | head -1)"
if [[ -n "${MAC91}" && -n "${MAC89}" && "${MAC91}" == "${MAC89}" ]]; then
echo " ARP MAC 与 89(192.168.2.101) 相同 → .100 是误绑,91 并没有回包。"
fi
echo " 91 请接控制柜 User Port 1(出厂静态 192.168.2.100)到同一交换机,示教器 AUTO+Remote Ethernet。"
echo " 89=192.168.2.101 91=192.168.2.100"
fi
echo "=== RDK preflight + tool (${ROBOT_SN}) ==="
TOOL_NAME="${SITE_ROBOT_TOOL_NAME:-}"
RDK_TOOL_ARGS=(--sn "${ROBOT_SN}")
if [[ -n "${NET_IFACE}" ]]; then
RDK_TOOL_ARGS+=(--iface "${NET_IFACE}")
fi
if [[ -n "${TOOL_NAME}" ]]; then
RDK_TOOL_ARGS+=(--name "${TOOL_NAME}")
echo "=== Studio tool → ${TOOL_NAME} ==="
fi
if ! "${RDK_PYTHON}" "${ROOT}/scripts/rdk_switch_tool.py" "${RDK_TOOL_ARGS[@]}"; then
echo ""
echo "ERROR: RDK cannot connect / switch tool on ${ROBOT_SN}."
echo " 先确认 ping ${ROBOT_IP} 通(91=控制柜 User Port 1 → 192.168.2.100)。"
echo " Stop any other RDK client (this run_real.sh is exclusive)."
echo " On teach pendant: Settings → Remote → enable Ethernet/RDK remote mode."
echo " Test: bash ${ROOT}/scripts/test_rdk_python.sh ${ROBOT_SN}"
exit 1
fi
exec ros2 launch arm_bringup stack.launch.py backend:=real robot_sn:="${ROBOT_SN}" use_rviz:=false "$@"