主界面一屏要同时看臂、夹爪、相机和触觉,按钮再被拉高就会叠到画面上。相机按原分辨率走回调取最新帧,场景一动不再等红外齐帧把彩色丢掉。模型和相机都留在工位窗口里,启动默认不再弹 RViz。

验收:test_listed_arms 与 test_camera_preview 共 20 项通过。D435 1280×720 发布约 29 帧/秒。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
arm_dev
2026-10-15 16:20:35 +08:00
parent 76c9b9cc49
commit 7942014763
44 changed files with 1664 additions and 599 deletions
+101
View File
@@ -61,6 +61,107 @@ fi
# shellcheck disable=SC1091
source "${ROOT}/scripts/env.sh"
# 平行爪节点起来之后串口是它的。再开一次会报占用,开合就失效。
# 这时把命令交给节点已经在听的 /gripper/ctrl。
pgea_node_up() {
local line
while IFS= read -r line; do
[[ "${line}" == *pgrep* ]] && continue
[[ -n "${line}" ]] && return 0
done < <(pgrep -af 'dh_pgea_node.py|lib/arm_application/dh_pgea' 2>/dev/null || true)
return 1
}
# 控制前把平行爪驱动拉起来。不 pkill 已经在跑的节点,也不写 0xA5。
# auto_init 用 site 里这一臂的值(现场是 false,回零会把夹着的件丢掉)。
# setsid:命令脚本退出后驱动还在,不会跟着会话一起被挂断。
ensure_pgea_node() {
if pgea_node_up; then
return 0
fi
local port="${SITE_GRIP_PORT:-/dev/ttyUSB0}"
if [[ ! -e "${port}" ]]; then
echo "ERROR: ${port} 不在。USB–RS485 没插上,夹爪驱动起不来。" >&2
return 1
fi
local node_py="${ROOT}/src/arm_application/arm_application/dh_pgea_node.py"
local short="${SITE_ROBOT_SHORT_ID:-89}"
local log_dir="/tmp/orisys_console"
local log="${log_dir}/gripper_node_${short}.log"
local auto="${SITE_GRIP_AUTO_INIT:-true}"
mkdir -p "${log_dir}"
echo "=== 平行爪驱动没在跑,先拉起来(auto_init=${auto},不另写回零) ${port} ==="
setsid python3 "${node_py}" --ros-args \
-p port:="${port}" \
-p baud:="${SITE_GRIP_BAUD:-115200}" \
-p slave_id:="${SITE_GRIP_SLAVE:-1}" \
-p stroke_mm:="${SITE_GRIP_STROKE_MM:-20.0}" \
-p force_pct:="${SITE_GRIP_FORCE:-50}" \
-p speed_pct:="${SITE_GRIP_SPEED:-50}" \
-p auto_init:="${auto}" \
-p model:="${MODEL}" \
-p "serial_number:='${SITE_GRIP_SN:-}'" \
-p "rs485_rts:='${SITE_GRIP_RS485_RTS:-}'" \
>>"${log}" 2>&1 < /dev/null &
local pid=$!
local i
for i in $(seq 1 24); do
if ! kill -0 "${pid}" 2>/dev/null; then
echo "ERROR: 夹爪驱动起来就退出了。" >&2
tail -n 30 "${log}" >&2 || true
return 1
fi
if timeout 2 ros2 topic echo /gripper/states --once >/dev/null 2>&1; then
echo "=== 夹爪驱动已在发 /gripper/states(pid ${pid})==="
return 0
fi
done
echo "ERROR: 夹爪驱动没有发出 /gripper/states。" >&2
tail -n 30 "${log}" >&2 || true
kill "${pid}" 2>/dev/null || true
return 1
}
if [[ ${#CLI[@]} -gt 0 && "${IS_ROTARY}" -eq 0 ]]; then
ensure_pgea_node || exit 1
fi
if [[ ${#CLI[@]} -gt 0 && "${IS_ROTARY}" -eq 0 ]] && pgea_node_up; then
export PYTHONPATH="${ROOT}/src/arm_application${PYTHONPATH:+:${PYTHONPATH}}"
export GRIP_CMD="${CLI[0]}"
export GRIP_VAL="${CLI[1]:-}"
export GRIP_FORCE="${GRIP_FORCE:-${SITE_GRIP_FORCE:-50}}"
export GRIP_SPEED="${GRIP_SPEED:-${SITE_GRIP_SPEED:-50}}"
echo "=== 平行爪节点已占 ${SITE_GRIP_PORT:-/dev/ttyUSB0},命令走 /gripper/ctrl ==="
CTRL="$(python3 - <<'PY'
import os
from arm_application.dh_pgea import ctrl_values
vals = ctrl_values(
os.environ.get("GRIP_CMD", ""),
os.environ.get("GRIP_VAL", ""),
int(os.environ.get("GRIP_FORCE") or "50"),
int(os.environ.get("GRIP_SPEED") or "50"),
)
if vals is None:
raise SystemExit(2)
print(", ".join(str(v) for v in vals))
PY
)" && rc=0 || rc=$?
if [[ "${rc}" -eq 2 ]]; then
exec timeout 4 ros2 topic echo /gripper/states --once
fi
if [[ "${rc}" -ne 0 ]]; then
echo "ERROR: 无法把夹爪命令转成 /gripper/ctrl" >&2
exit 1
fi
exec timeout 8 ros2 topic pub --once /gripper/ctrl std_msgs/msg/Float32MultiArray "{data: [${CTRL}]}"
fi
if [[ ${#CLI[@]} -gt 0 && "${IS_ROTARY}" -eq 0 ]]; then
echo "ERROR: 平行爪命令没有送到 /gripper/ctrl。" >&2
exit 1
fi
if [[ ${#CLI[@]} -gt 0 ]]; then
if [[ "${IS_ROTARY}" -eq 1 ]]; then
CMD="${CLI[0]}"