update sub modules features and kill/launch/README @huiyu

This commit is contained in:
NuoDaJia02
2026-01-15 15:54:33 +08:00
parent 509be9bbef
commit c417bb0bde
12 changed files with 261 additions and 52 deletions

3
.gitignore vendored
View File

@@ -21,4 +21,5 @@ camera_pose_data.json
eye_to_hand_matrix.json
hand_pose_data.json
.vscode/
.vscode/
logs/

View File

@@ -1,6 +1,32 @@
# hivecore_robot_vision
# 1. hivecore_robot_os1
## 使用教程
1. 启动节点
```bash
# 启动 launch.conf 中配置的所有节点
./launch_robot.sh all
# 仅启动特定节点(支持多个,名称对应 launch.conf 中的 pkg 或 target
./launch_robot.sh <node_name1> <node_name2> ...
# 例如: ./launch_robot.sh robot_control
```
2. 控制终端
```
打开浏览器,输入 http://192.168.0.39:8080/ 启动web服务ip地址为运行设备的ip地址
```
3. 杀掉节点
```bash
# 杀掉所有相关节点进程
./kill_robot.sh all
# 仅杀掉特定节点进程
./kill_robot.sh <node_name1> <node_name2> ...
# 例如: ./kill_robot.sh vision_detect
```
# 2. hivecore_robot_vision
#### 安装教程

View File

@@ -1,7 +1,6 @@
# source /opt/ros/humble/setup.bash
# sudo -E ros2 launch ethercat_control ethercat_node.launch.py
# chrt -f 40 \
# taskset -c 7 \
#!/bin/bash
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
source /opt/ros/humble/setup.bash
source "${SCRIPT_DIR}/install/setup.bash"
ros2 launch ethercat_control ethercat_node.launch.py

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env bash
# ./kill_robot.sh # kill ROS 2 processes from this workspace
# ./kill_robot.sh [node_names...] # kill specific nodes
# ./kill_robot.sh all # kill all ROS 2 processes from this workspace
# ./kill_robot.sh -A # kill all ROS 2 processes system-wide (dangerous)
# ./kill_robot.sh -n # dry run (show PIDs only)
# ./kill_robot.sh -y # no confirmation
@@ -14,36 +15,79 @@ SCOPE_ALL=false
DRY_RUN=false
ASSUME_YES=false
VERBOSE=false
TARGET_NODES=()
log() { echo "[kill_ros2] $*"; }
vlog() { $VERBOSE && echo "[kill_ros2][debug] $*" || true; }
usage() {
cat <<EOF
Usage: $(basename "$0") [options]
Options:
-A Kill all ROS 2 processes system-wide (not only this workspace)
-n Dry run (list candidate PIDs and commands)
-y Assume yes (no confirmation prompt)
-v Verbose output
-h Show this help and exit
Env:
WS_DIR Workspace directory (default: script directory)
EOF
}
while getopts ":Anyvh" opt; do
case $opt in
A) SCOPE_ALL=true ;;
n) DRY_RUN=true ;;
y) ASSUME_YES=true ;;
v) VERBOSE=true ;;
h) usage; exit 0 ;;
:) echo "Option -$OPTARG requires an argument" >&2; exit 2 ;;
\?) echo "Unknown option: -$OPTARG" >&2; usage; exit 2 ;;
# Parse arguments
# Collect options first, remaining args are target nodes.
while [[ $# -gt 0 ]]; do
case "$1" in
-A|--all-system)
SCOPE_ALL=true
shift
;;
-n|--dry-run)
DRY_RUN=true
shift
;;
-y|--yes)
ASSUME_YES=true
shift
;;
-v|--verbose)
VERBOSE=true
shift
;;
-h|--help)
echo "Usage: $0 [OPTIONS] [NODE_NAMES... | all]"
echo " all Kill ALL ROS 2 nodes associated with workspace (default behavior if no nodes specified AND 'all' is passed)"
echo " NODE_NAMES... List of node executable names or keywords to kill (e.g., 'rm_arm_node')"
echo "Options:"
echo " -A, --all-system Kill ALL ROS 2 processes system-wide (ignores workspace check)"
echo " -n, --dry-run Print PIDs that would be killed, but don't kill them"
echo " -y, --yes Skip confirmation prompt"
echo " -v, --verbose Enable verbose logging"
exit 0
;;
*)
TARGET_NODES+=("$1")
shift
;;
esac
done
if [ ${#TARGET_NODES[@]} -eq 0 ] && [ "$SCOPE_ALL" = false ]; then
echo "Error: No target nodes specified. Please provide node names or use 'all'."
echo "Usage: $0 [node1 node2 ...] | all"
exit 1
fi
if [[ "${#TARGET_NODES[@]}" -eq 1 && "${TARGET_NODES[0]}" == "all" ]]; then
log "Mode: KILL ALL workspace nodes"
TARGET_NODES=() # Clear target list to trigger full workspace kill logic
# Falls through to existing logic
elif [[ ${#TARGET_NODES[@]} -gt 0 ]]; then
log "Mode: KILL SPECIFIC nodes: ${TARGET_NODES[*]}"
fi
usage() {
cat <<EOF
Usage: $(basename "$0") [OPTIONS] [NODE_NAMES... | all]
Options:
-A, --all-system Kill all ROS 2 processes system-wide (not only this workspace)
-n, --dry-run Dry run (list candidate PIDs and commands)
-y, --yes Assume yes (no confirmation prompt)
-v, --verbose Verbose output
-h, --help Show this help and exit
Arguments:
all Kill ALL ROS 2 nodes associated with workspace
NODE_NAMES... List of node executable names or keywords to kill
EOF
}
# Return 0 if PID is alive, else 1
is_alive() { kill -0 "$1" 2>/dev/null; }
@@ -65,6 +109,18 @@ list_candidates() {
cmd=${line#* } # everything after first space
# Skip self
[[ "$pid" -eq $$ || "$pid" -eq $PPID ]] && continue
# --- Filter by specific node names first if provided ---
if [[ ${#TARGET_NODES[@]} -gt 0 ]]; then
local match_found=false
for target in "${TARGET_NODES[@]}"; do
if grep -q "$target" <<<"$cmd"; then
match_found=true
break
fi
done
$match_found || continue
fi
# Scope filter
local in_scope=false
@@ -72,7 +128,7 @@ list_candidates() {
in_scope=true
else
# Focus on processes started from this workspace or via ros2 run/launch
if grep -qE "/install/.*/lib/" <<<"$cmd" ||
if grep -qE "/install/.*/lib/|/opt/ros/.*/lib/" <<<"$cmd" ||
grep -qE "\bros2 (run|launch)\b" <<<"$cmd" ||
grep -qE "python(3)? .*launch" <<<"$cmd"; then
# If workspace path is known, prefer matches containing it

View File

@@ -5,11 +5,11 @@
#DRIVER|launch|ethercat_control|ethercat_node.launch.py|
#DRIVER|run|led_dev|led_dev_node|
#MOTOR|run|motor_dev|motor_dev_node|
# IMU|launch|imu_dev|imu_dev.launch.py|
#IMU|run|openzen_driver|openzen_node|
#IMU|launch|imu_dev|imu_dev.launch.py|
ARM|launch|rm_arm_control|rm_arm_control.launch.py|
#IMG|launch|img_dev|img_dev.launch.py|
#BRAIN|run|brain|brain_node|
IMG|launch|img_dev|img_dev.launch.py|
TOOL|run|ctrlgui|ctrlgui_node|
#MOTION|launch|robot_control|robot_control.launch.py|
VISION|launch|vision_detect|medical_sense.launch.py|
GRIPPER|launch|gripper_dev|gripper_dev.launch.py|
BRAIN|launch|brain|brain.launch.py|
#MOTION|launch|robot_control|robot_control.launch.py|

View File

@@ -1,13 +1,44 @@
#!/usr/bin/env bash
# ./launch_robot.sh [node_names...] # launch specific nodes
# ./launch_robot.sh all # launch all nodes in launch.conf
# Safer bash defaults for this script
set -Eeuo pipefail
# Argument check
TARGET_NODES=()
LAUNCH_ALL=false
if [ $# -eq 0 ]; then
echo "Error: No target nodes specified."
echo "Usage: $0 [node1 node2 ...] | all"
exit 1
fi
if [[ "$1" == "all" ]]; then
LAUNCH_ALL=true
else
TARGET_NODES=("$@")
fi
# Workspace directory defaults to the current working directory when the script is run
WS_DIR="${WS_DIR:-$PWD}"
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
CONFIG_FILE="${CONFIG_FILE:-${SCRIPT_DIR}/launch.conf}"
# 获取日期和时间戳函数
date_day() { date +"%Y%m%d"; }
readable_timestamp() { date +"%Y%m%d_%H%M%S"; }
# 1. 自动创建当天的日志根目录并包含本次启动的时间子目录
DAILY_LOG_ROOT="${WS_DIR}/logs/$(date_day)"
LOG_DIR="${DAILY_LOG_ROOT}/robot_logs_$(readable_timestamp)"
mkdir -p "${LOG_DIR}"
# 2. 导出 ROS_LOG_DIR 环境变量,确保 ROS 2 进程的内部日志也保存在该目录下
export ROS_LOG_DIR="${LOG_DIR}"
# title|mode|package|target|args
# mode: run => ros2 run <pkg> <executable>
# launch => ros2 launch <pkg> <launch_file.py>
@@ -36,7 +67,24 @@ launch_with_gnome_terminal() {
# Build unique title list
local unique_titles=()
for entry in "${COMPONENTS[@]}"; do
IFS='|' read -r title _ _ _ _ <<<"$entry"
IFS='|' read -r title mode pkg target args <<<"$entry"
# --- Filter Logic ---
if [ "$LAUNCH_ALL" = false ]; then
local match_found=false
for node_filter in "${TARGET_NODES[@]}"; do
# Match against package name or executable name
if [[ "$node_filter" == "$pkg" ]] || [[ "$node_filter" == "$target" ]]; then
match_found=true
break
fi
done
if [ "$match_found" = false ]; then
continue
fi
fi
# --------------------
local found=0
for t in "${unique_titles[@]:-}"; do
if [[ "$t" == "$title" ]]; then found=1; break; fi
@@ -50,21 +98,51 @@ launch_with_gnome_terminal() {
for entry in "${COMPONENTS[@]}"; do
IFS='|' read -r etitle mode pkg target args <<<"$entry"
[[ "$etitle" != "$title" ]] && continue
# --- Filter Logic (Repeated for execution block) ---
if [ "$LAUNCH_ALL" = false ]; then
local match_found=false
for node_filter in "${TARGET_NODES[@]}"; do
# Match against package name or executable name
if [[ "$node_filter" == "$pkg" ]] || [[ "$node_filter" == "$target" ]]; then
match_found=true
break
fi
done
if [ "$match_found" = false ]; then
continue
fi
fi
# --------------------
args="${args:-}"
local ros_cmd
if [[ "$mode" == "launch" ]]; then
if [[ "${pkg}" == "ethercat_control" ]]; then
ros_cmd="taskset -c 7 ./cpu7.sh"
elif [[ "$mode" == "launch" ]]; then
ros_cmd="ros2 launch ${pkg} ${target} ${args}"
else
ros_cmd="ros2 run ${pkg} ${target} ${args}"
fi
cmds_block+="${ros_cmd} "$'\n'
if [[${pkg} == "ethercat_control"]]; then
cmds_block="taskset -c 7 ./cpu7.sh"
if [[ "${pkg}" == "robot_control" ]]; then
ros_cmd="echo 'Waiting for EtherCAT slaves to be OP...'; while ! ethercat slaves 2>&1 | grep -q 'OP' || ethercat slaves 2>&1 | grep -v 'OP' | grep -q .; do sleep 2; done; ${ros_cmd}"
fi
# 3. 为每个组件生成带明文时间戳的日志文件名并添加重定向
local log_file="${LOG_DIR}/${etitle}_${target}_$(readable_timestamp).log"
ros_cmd="{ ${ros_cmd}; } 2>&1 | tee \"${log_file}\""
cmds_block+="${ros_cmd} &"$'\n'
done
# If no commands collected for this title (because all were filtered out), skip launching terminal
if [[ -z "$cmds_block" ]]; then continue; fi
# Compose the final script for this terminal
local cmd
cmd=$(compose_terminal_script "$title" "$cmds_block")
# gnome-terminal --title="${title}" -- bash -lc "$cmd" &
bash -c "$cmd" &
sleep 3
@@ -73,7 +151,24 @@ launch_with_gnome_terminal() {
launch_with_xterm() {
local unique_titles=()
for entry in "${COMPONENTS[@]}"; do
IFS='|' read -r title _ _ _ _ <<<"$entry"
IFS='|' read -r title mode pkg target args <<<"$entry"
# --- Filter Logic ---
if [ "$LAUNCH_ALL" = false ]; then
local match_found=false
for node_filter in "${TARGET_NODES[@]}"; do
# Match against package name or executable name
if [[ "$node_filter" == "$pkg" ]] || [[ "$node_filter" == "$target" ]]; then
match_found=true
break
fi
done
if [ "$match_found" = false ]; then
continue
fi
fi
# --------------------
local found=0
for t in "${unique_titles[@]:-}"; do
if [[ "$t" == "$title" ]]; then found=1; break; fi
@@ -86,15 +181,47 @@ launch_with_xterm() {
for entry in "${COMPONENTS[@]}"; do
IFS='|' read -r etitle mode pkg target args <<<"$entry"
[[ "$etitle" != "$title" ]] && continue
# --- Filter Logic (Repeated for execution block) ---
if [ "$LAUNCH_ALL" = false ]; then
local match_found=false
for node_filter in "${TARGET_NODES[@]}"; do
# Match against package name or executable name
if [[ "$node_filter" == "$pkg" ]] || [[ "$node_filter" == "$target" ]]; then
match_found=true
break
fi
done
if [ "$match_found" = false ]; then
continue
fi
fi
# --------------------
args="${args:-}"
local ros_cmd
if [[ "$mode" == "launch" ]]; then
if [[ "${pkg}" == "ethercat_control" ]]; then
ros_cmd="taskset -c 7 ./cpu7.sh"
elif [[ "$mode" == "launch" ]]; then
ros_cmd="ros2 launch ${pkg} ${target} ${args}"
else
ros_cmd="ros2 run ${pkg} ${target} ${args}"
fi
if [[ "${pkg}" == "robot_control" ]]; then
ros_cmd="echo 'Waiting for EtherCAT slaves to be OP...'; while ! ethercat slaves 2>&1 | grep -q 'OP' || ethercat slaves 2>&1 | grep -v 'OP' | grep -q .; do sleep 2; done; ${ros_cmd}"
fi
# 3. 为每个组件生成带明文时间戳的日志文件名并添加重定向
local log_file="${LOG_DIR}/${etitle}_${target}_$(readable_timestamp).log"
ros_cmd="{ ${ros_cmd}; } 2>&1 | tee \"${log_file}\""
cmds_block+="${ros_cmd} &"$'\n'
done
# If no commands collected for this title (because all were filtered out), skip launching terminal
if [[ -z "$cmds_block" ]]; then continue; fi
local cmd
cmd=$(compose_terminal_script "$title" "$cmds_block")
xterm -T "${title}" -hold -e bash -lc "$cmd" &
@@ -109,8 +236,8 @@ main() {
echo "Using xterm"
launch_with_xterm
else
echo "No terminal emulator found (gnome-terminal or xterm). Please install one and retry." >&2
exit 1
echo "No terminal emulator found (gnome-terminal or xterm). Proceeding with background execution." >&2
launch_with_gnome_terminal
fi
}