6baf989595
实测(2026-09-28)在仿真里上料失败,一路查到 IK / TF / 时钟上,全是被冤枉的。 根因是两个真机侧一直缺的东西: 1) **真机侧没有停止脚本**。仿真侧早有 stop_sim_gz.sh(R4.10/R4.11:残留会伪造出 "代码写错了"的现场),真机侧只有 run_real.sh 里两行 pkill。而真机栈里有一族 **独立于 ros2_control_node 存活**的进程 —— 上一轮栈的主体早没了,只剩 real_trajectory_adapter / named_pose_server / arm_status_node / joint_state_publisher 四条,两条 pkill 一条都匹配不到。 危害不是占资源而是**冒名顶替**:残留的 adapter 照样订阅 /trajectory、 残留的 joint_state_publisher 照样发 /joint_states(mock 的静态关节角)。 现象极具误导性:控制器 feedback 与 reference 完全一致(控制器没坏), TF 却显示末端一动不动。 新增 stop_real.sh + lib/real_procs.sh:扫描 = 点名表 + `install/` 前缀兜底, 按 ROS_DOMAIN_ID 判别真机/仿真(两边有同名的 robot_state_publisher, 否则停真机会把正在跑的仿真杀一半),杀完复查残留并非零退出。 run_real.sh 启动前的清理改用它,不再各写一份会漂移的模式表。 真机侧**有意不**用仿真的"进程组"法:真机栈是前台交互跑的,没有独立进程组, 它的 PGID 就是调用它的 shell —— 记下来再 kill 会杀掉自己的终端。 2) **真机侧不强制 ROS_DOMAIN_ID**。sim_env.sh 早就强制 77 并写明"隔离不能靠 『环境里恰好没设』",真机侧没有对应保护:先 source 过 sim_env.sh 的 shell 里 再起真机栈,真机栈就落到**仿真的域**上,节点名撞车、/joint_states 与 /tf 各有两个来源互相盖。补 lib/ros_domain.sh(真机 0 / 覆盖用 REAL_ROS_DOMAIN_ID), env.sh、run_real.sh、run_sim.sh 三处共用一份实现 —— 成对强制,否则一侧的 强制只是把运气挪到了另一侧。 run_sim.sh 特别容易漏:它名为 sim,用的却是**真机的 install/**、节点名与真机 完全一样,而且当时不管域;这次也钉到真机域 0。run_sim_gz.sh 文件头那句 "两者互不影响"是错的,一并改掉。 验证:stop_real.sh --list 在有仿真在跑时为空(REAL_PROC_INCLUDE_SIM=1 能看到 并按"域 77"标出);伪装一个 install/arm_control/lib/arm_control/arm_status_node 的孤儿进程能被点名。新增 6 项单测钉住域的四种输入 + 一个不许误报。 Co-authored-by: Cursor <cursoragent@cursor.com>
55 lines
2.1 KiB
Bash
Executable File
55 lines
2.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# 加载本工作区环境(conda + ROS + flexiv 库)。
|
||
# 用法:source scripts/env.sh
|
||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||
|
||
if [[ -f /opt/ros/humble/setup.bash ]]; then
|
||
# shellcheck disable=SC1091
|
||
source /opt/ros/humble/setup.bash
|
||
elif [[ -f /opt/ros/jazzy/setup.bash ]]; then
|
||
# shellcheck disable=SC1091
|
||
source /opt/ros/jazzy/setup.bash
|
||
fi
|
||
|
||
if [[ -f "${HOME}/anaconda3/etc/profile.d/conda.sh" ]]; then
|
||
# shellcheck disable=SC1091
|
||
source "${HOME}/anaconda3/etc/profile.d/conda.sh"
|
||
# 干净切换:先把堆叠的激活退到 base,再激活真机环境。
|
||
# 同一 shell 里从仿真环境(ros_gz_sim)切过来时,不清干净会残留 PATH/PYTHONPATH,
|
||
# 导致 python/pip 解析到另一个环境的包,构建报 "--editable not recognized"
|
||
# 之类与真实原因无关的错。详见 scripts/lib/conda_switch.sh。
|
||
_env_helper="${ROOT}/scripts/lib/conda_switch.sh"
|
||
if [[ -f "${_env_helper}" ]]; then
|
||
# shellcheck disable=SC1090
|
||
source "${_env_helper}"
|
||
conda_switch_clean "ros_flexiv" "${SIM_ENV_NAME:-ros_gz_sim}" || \
|
||
conda activate ros_flexiv 2>/dev/null || true
|
||
else
|
||
conda activate ros_flexiv 2>/dev/null || true
|
||
fi
|
||
unset _env_helper
|
||
fi
|
||
|
||
# shellcheck disable=SC1091
|
||
source "${ROOT}/install/setup.bash"
|
||
export LD_LIBRARY_PATH="${HOME}/flexiv_install/lib:${LD_LIBRARY_PATH:-}"
|
||
# pip 版 TensorRT(tensorrt-cu12)—— 加载 YOLO `.engine` 需要它
|
||
_TRT_SITE="${CONDA_PREFIX:-${HOME}/anaconda3/envs/ros_flexiv}/lib/python3.11/site-packages"
|
||
for _d in "${_TRT_SITE}/tensorrt" "${_TRT_SITE}/tensorrt_libs" "${_TRT_SITE}/nvidia/tensorrt/lib"; do
|
||
if [[ -d "${_d}" ]]; then
|
||
export LD_LIBRARY_PATH="${_d}:${LD_LIBRARY_PATH}"
|
||
fi
|
||
done
|
||
unset _d _TRT_SITE
|
||
export YOLO_AUTOINSTALL=false
|
||
export ROS2_WS="${ROOT}"
|
||
|
||
# 真机与仿真的 DDS 隔离(细节与踩坑见 lib/ros_domain.sh 的文件头)。
|
||
# shellcheck source=lib/ros_domain.sh
|
||
source "${ROOT}/scripts/lib/ros_domain.sh"
|
||
ros_domain_force_real
|
||
|
||
# 主站点配置 → `SITE_*`(YOLO 权重、相机、机器人 SN……)
|
||
# shellcheck disable=SC1091
|
||
source "${ROOT}/scripts/lib/load_site_config.sh" 2>/dev/null || true
|