Update mission flow and inspection log scrolling
This commit is contained in:
@@ -0,0 +1,31 @@
|
|||||||
|
# Repository Guidelines
|
||||||
|
|
||||||
|
## 项目结构与模块组织
|
||||||
|
|
||||||
|
本仓库是 AGV 智能巡检系统,后端、前端、ROS2 启动链路分目录维护。`agv_app/` 是 Flask 后端,包含 API、模板、静态资源与 `data/*.json` 持久化配置;`agv_app/utils/` 放置 AGV、Nav2、机械臂、二维码与任务执行逻辑。`arm_server/` 是机械臂端 TCP/摄像头服务及 systemd 配置。`scan_fixer/` 提供生产链路中的 ROS2 时间戳修正工具。`public-frontend/` 是 Next.js 平板端,源码在 `src/app`、`src/components`、`src/services`、`src/store`、`src/types`。`scripts/` 与 `Makefile` 负责本地开发、生产启动和停止流程,`docs/` 存放技术文档。
|
||||||
|
|
||||||
|
## 构建、测试与开发命令
|
||||||
|
|
||||||
|
- `make install`:执行 `uv sync` 并安装前端 npm 依赖。
|
||||||
|
- `make dev`:显示本地开发启动说明。
|
||||||
|
- `make dev-backend`:以 Mock 硬件模式启动 Flask 后端。
|
||||||
|
- `make dev-frontend`:启动 Next.js 开发服务器。
|
||||||
|
- `make prod`:在 AGV 上启动 ROS2、Nav2、scan fixer 与 Flask 完整生产链路。
|
||||||
|
- `cd public-frontend && npm run build`:构建前端。
|
||||||
|
- `cd public-frontend && npm run lint && npm run typecheck`:执行前端 lint 与 TypeScript 检查。
|
||||||
|
|
||||||
|
## 编码风格与命名约定
|
||||||
|
|
||||||
|
Python 目标版本为 3.10,依赖由根目录 `pyproject.toml` 和 `uv.lock` 管理。保持模块职责清晰,配置集中放在 `agv_app/config.py`,复用硬件抽象时优先放入 `agv_app/utils/`。前端使用 TypeScript、React、Next.js App Router 与 Ant Design;组件使用 PascalCase,例如 `CameraFrame.tsx`,服务和工具使用 camelCase,例如 `apiClient.ts`。新增代码应自解释命名,避免魔术值,必要注释只说明业务背景或非常规取舍。
|
||||||
|
|
||||||
|
## 测试指南
|
||||||
|
|
||||||
|
当前仓库未配置独立单元测试框架。提交前至少运行相关静态检查:前端改动运行 `npm run lint` 和 `npm run typecheck`,后端改动用 `make dev-backend` 做 Flask 启动与关键接口冒烟验证。涉及硬件、ROS2 或生产脚本的改动,应说明是否已在真实 AGV 或 Mock 模式验证。
|
||||||
|
|
||||||
|
## 提交与 Pull Request 规范
|
||||||
|
|
||||||
|
历史提交主要使用英文祈使句式,例如 `Improve camera status and production startup`、`Refactor ROS startup scripts`、`Fix shell compatibility issues in prod-backend.sh`。继续使用简短英文提交信息,避免无意义占位。PR 应包含变更摘要、验证命令、硬件/环境影响、相关 issue;前端界面变化需附截图或录屏,生产启动链路变化需列出影响的脚本和服务。
|
||||||
|
|
||||||
|
## 安全与配置提示
|
||||||
|
|
||||||
|
不要提交新的密钥、令牌、设备私有地址或本地日志。环境示例放在 `.env.example`,运行时覆盖优先使用环境变量,例如 `BACKEND_URL`、`MOCK_HARDWARE`、`AGV_PROJECT_DIR`。涉及 AGV、机械臂或 ROS2 生产配置时,先核对 `scripts/README.md` 中的默认路径与日志位置。
|
||||||
+81
-4
@@ -46,6 +46,15 @@ logging.basicConfig(
|
|||||||
)
|
)
|
||||||
logger = logging.getLogger("agv_app")
|
logger = logging.getLogger("agv_app")
|
||||||
|
|
||||||
|
ORIGIN_X = 0.0
|
||||||
|
ORIGIN_Y = 0.0
|
||||||
|
ORIGIN_YAW = 0.0
|
||||||
|
ORIGIN_MATCH_TOLERANCE = 1e-6
|
||||||
|
ARM_RETURN_SPEED = 500
|
||||||
|
ARM_INITIAL_POSE_TIMEOUT = 15.0
|
||||||
|
ARM_INITIAL_POSE_TOLERANCE = 2.0
|
||||||
|
ARM_INITIAL_POSE_UNSET_TOLERANCE = 0.01
|
||||||
|
|
||||||
app = Flask(__name__, template_folder="templates", static_folder="static", static_url_path="/static")
|
app = Flask(__name__, template_folder="templates", static_folder="static", static_url_path="/static")
|
||||||
app.config["SECRET_KEY"] = SERVER_CONFIG["secret_key"]
|
app.config["SECRET_KEY"] = SERVER_CONFIG["secret_key"]
|
||||||
CORS(app)
|
CORS(app)
|
||||||
@@ -88,6 +97,60 @@ gs = GlobalState()
|
|||||||
|
|
||||||
|
|
||||||
# ========== 辅助函数 ==========
|
# ========== 辅助函数 ==========
|
||||||
|
def _is_origin_goal(x: float, y: float, yaw: float = None) -> bool:
|
||||||
|
yaw_is_origin = yaw is None or abs(yaw - ORIGIN_YAW) <= ORIGIN_MATCH_TOLERANCE
|
||||||
|
return (
|
||||||
|
abs(x - ORIGIN_X) <= ORIGIN_MATCH_TOLERANCE
|
||||||
|
and abs(y - ORIGIN_Y) <= ORIGIN_MATCH_TOLERANCE
|
||||||
|
and yaw_is_origin
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_arm_pose(raw_pose):
|
||||||
|
if not isinstance(raw_pose, list) or len(raw_pose) != 6:
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
return [float(angle) for angle in raw_pose]
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _wait_arm_initial_pose(target_angles, timeout=ARM_INITIAL_POSE_TIMEOUT, tolerance=ARM_INITIAL_POSE_TOLERANCE):
|
||||||
|
deadline = time.time() + timeout
|
||||||
|
while time.time() < deadline:
|
||||||
|
try:
|
||||||
|
ok, current_angles = gs.arm_client.get_angles()
|
||||||
|
if ok and current_angles and len(current_angles) >= 6:
|
||||||
|
current_angles = [float(angle) for angle in current_angles[:6]]
|
||||||
|
if all(abs(current_angles[index] - target_angles[index]) <= tolerance for index in range(6)):
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"等待机械臂初始姿态失败: {e}")
|
||||||
|
time.sleep(0.5)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _restore_arm_initial_pose_for_origin():
|
||||||
|
arm_initial_pose = _normalize_arm_pose(gs.mission_config.get("arm_initial_pose"))
|
||||||
|
if not arm_initial_pose:
|
||||||
|
return {"ok": True, "skipped": True, "message": "未配置有效机械臂初始姿态,跳过复原"}
|
||||||
|
if not any(abs(angle) > ARM_INITIAL_POSE_UNSET_TOLERANCE for angle in arm_initial_pose):
|
||||||
|
return {"ok": True, "skipped": True, "message": "未配置机械臂初始姿态,跳过复原"}
|
||||||
|
if not gs.arm_client:
|
||||||
|
return {"ok": False, "error": "机械臂未连接,无法先复原再回原点"}
|
||||||
|
|
||||||
|
try:
|
||||||
|
ok = gs.arm_client.set_angles(arm_initial_pose, ARM_RETURN_SPEED)
|
||||||
|
if not ok:
|
||||||
|
return {"ok": False, "error": "机械臂初始姿态指令发送失败,已取消回原点"}
|
||||||
|
if not _wait_arm_initial_pose(arm_initial_pose):
|
||||||
|
return {"ok": False, "error": "机械臂未在规定时间内复原,已取消回原点"}
|
||||||
|
return {"ok": True, "skipped": False, "message": "机械臂已复原到初始姿态"}
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"回原点前复原机械臂失败: {e}")
|
||||||
|
return {"ok": False, "error": f"回原点前复原机械臂失败: {e}"}
|
||||||
|
|
||||||
|
|
||||||
def get_data_path(name):
|
def get_data_path(name):
|
||||||
return os.path.join(DATA_DIR, name)
|
return os.path.join(DATA_DIR, name)
|
||||||
|
|
||||||
@@ -464,24 +527,38 @@ def api_navigate_to():
|
|||||||
if not gs.map_config or "map_yaml" not in gs.map_config:
|
if not gs.map_config or "map_yaml" not in gs.map_config:
|
||||||
return jsonify({"ok": False, "error": "地图未加载,请先在设置中加载地图"}), 400
|
return jsonify({"ok": False, "error": "地图未加载,请先在设置中加载地图"}), 400
|
||||||
|
|
||||||
data = request.json
|
data = request.json or {}
|
||||||
goal_x = data.get("x")
|
goal_x = data.get("x")
|
||||||
goal_y = data.get("y")
|
goal_y = data.get("y")
|
||||||
goal_yaw = data.get("yaw") # 姿态参数,可选
|
goal_yaw = data.get("yaw") # 姿态参数,可选
|
||||||
if goal_x is None or goal_y is None:
|
if goal_x is None or goal_y is None:
|
||||||
return jsonify({"ok": False, "error": "缺少目标坐标 x, y"}), 400
|
return jsonify({"ok": False, "error": "缺少目标坐标 x, y"}), 400
|
||||||
|
try:
|
||||||
|
goal_x = float(goal_x)
|
||||||
|
goal_y = float(goal_y)
|
||||||
|
yaw_arg = float(goal_yaw) if goal_yaw is not None else None
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
return jsonify({"ok": False, "error": "目标坐标格式错误"}), 400
|
||||||
|
|
||||||
if not gs.agv_controller or not gs.agv_controller.is_connected():
|
if not gs.agv_controller or not gs.agv_controller.is_connected():
|
||||||
return jsonify({"ok": False, "error": "AGV 未连接,请先连接 AGV"}), 400
|
return jsonify({"ok": False, "error": "AGV 未连接,请先连接 AGV"}), 400
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
restore_message = ""
|
||||||
|
restore_arm = bool(data.get("restore_arm", True))
|
||||||
|
if restore_arm and _is_origin_goal(goal_x, goal_y, yaw_arg):
|
||||||
|
restore_result = _restore_arm_initial_pose_for_origin()
|
||||||
|
if not restore_result["ok"]:
|
||||||
|
return jsonify({"ok": False, "error": restore_result["error"]}), 400
|
||||||
|
restore_message = restore_result.get("message", "")
|
||||||
|
|
||||||
if gs.navigator is None:
|
if gs.navigator is None:
|
||||||
gs.navigator = Nav2Navigator()
|
gs.navigator = Nav2Navigator()
|
||||||
# navigate_to_pose(x, y, yaw=None, timeout_sec=120, blocking=False)
|
# navigate_to_pose(x, y, yaw=None, timeout_sec=120, blocking=False)
|
||||||
yaw_arg = float(goal_yaw) if goal_yaw is not None else None
|
ok = gs.navigator.navigate_to_pose(goal_x, goal_y, yaw_arg, blocking=False)
|
||||||
ok = gs.navigator.navigate_to_pose(float(goal_x), float(goal_y), yaw_arg, blocking=False)
|
|
||||||
if ok:
|
if ok:
|
||||||
return jsonify({"ok": True, "message": "导航已启动"})
|
message = f"{restore_message},导航已启动" if restore_message else "导航已启动"
|
||||||
|
return jsonify({"ok": True, "message": message})
|
||||||
else:
|
else:
|
||||||
return jsonify({"ok": False, "error": "导航启动失败,可能是Nav2未运行或AGV未连接"}), 400
|
return jsonify({"ok": False, "error": "导航启动失败,可能是Nav2未运行或AGV未连接"}), 400
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
+212
-146
@@ -1,25 +1,4 @@
|
|||||||
[
|
[
|
||||||
{
|
|
||||||
"id": "m_2_0",
|
|
||||||
"row": 2,
|
|
||||||
"col": 0,
|
|
||||||
"front": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
"back": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "m_2_2",
|
"id": "m_2_2",
|
||||||
"row": 2,
|
"row": 2,
|
||||||
@@ -167,27 +146,6 @@
|
|||||||
"poses": []
|
"poses": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "m_0_4",
|
|
||||||
"row": 0,
|
|
||||||
"col": 4,
|
|
||||||
"front": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
"back": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "m_0_5",
|
"id": "m_0_5",
|
||||||
"row": 0,
|
"row": 0,
|
||||||
@@ -251,27 +209,6 @@
|
|||||||
"poses": []
|
"poses": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "m_2_1",
|
|
||||||
"row": 2,
|
|
||||||
"col": 1,
|
|
||||||
"front": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
"back": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "m_2_4",
|
"id": "m_2_4",
|
||||||
"row": 2,
|
"row": 2,
|
||||||
@@ -293,27 +230,6 @@
|
|||||||
"poses": []
|
"poses": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "m_2_5",
|
|
||||||
"row": 2,
|
|
||||||
"col": 5,
|
|
||||||
"front": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
"back": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "m_0_0",
|
"id": "m_0_0",
|
||||||
"row": 0,
|
"row": 0,
|
||||||
@@ -356,36 +272,6 @@
|
|||||||
"poses": []
|
"poses": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "m_0_1",
|
|
||||||
"row": 0,
|
|
||||||
"col": 1,
|
|
||||||
"front": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
"back": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
"qr": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"qr_value": "",
|
|
||||||
"model_id": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "m_0_2",
|
"id": "m_0_2",
|
||||||
"row": 0,
|
"row": 0,
|
||||||
@@ -416,36 +302,6 @@
|
|||||||
"model_id": ""
|
"model_id": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "m_0_3",
|
|
||||||
"row": 0,
|
|
||||||
"col": 3,
|
|
||||||
"front": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
"back": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
"qr": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"qr_value": "",
|
|
||||||
"model_id": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "m_1_1",
|
"id": "m_1_1",
|
||||||
"row": 1,
|
"row": 1,
|
||||||
@@ -506,6 +362,126 @@
|
|||||||
"model_id": ""
|
"model_id": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "m_1_4",
|
||||||
|
"row": 1,
|
||||||
|
"col": 4,
|
||||||
|
"front": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"qr": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"qr_value": "",
|
||||||
|
"model_id": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "m_0_6",
|
||||||
|
"row": 0,
|
||||||
|
"col": 6,
|
||||||
|
"front": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"qr": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"qr_value": "",
|
||||||
|
"model_id": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "m_1_6",
|
||||||
|
"row": 1,
|
||||||
|
"col": 6,
|
||||||
|
"front": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"qr": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"qr_value": "",
|
||||||
|
"model_id": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "m_0_3",
|
||||||
|
"row": 0,
|
||||||
|
"col": 3,
|
||||||
|
"front": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"qr": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"qr_value": "",
|
||||||
|
"model_id": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "m_1_3",
|
"id": "m_1_3",
|
||||||
"row": 1,
|
"row": 1,
|
||||||
@@ -537,8 +513,98 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "m_1_4",
|
"id": "m_2_0",
|
||||||
"row": 1,
|
"row": 2,
|
||||||
|
"col": 0,
|
||||||
|
"front": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"qr": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"qr_value": "",
|
||||||
|
"model_id": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "m_2_1",
|
||||||
|
"row": 2,
|
||||||
|
"col": 1,
|
||||||
|
"front": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"qr": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"qr_value": "",
|
||||||
|
"model_id": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "m_0_1",
|
||||||
|
"row": 0,
|
||||||
|
"col": 1,
|
||||||
|
"front": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"qr": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"qr_value": "",
|
||||||
|
"model_id": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "m_0_4",
|
||||||
|
"row": 0,
|
||||||
"col": 4,
|
"col": 4,
|
||||||
"front": {
|
"front": {
|
||||||
"coords": [
|
"coords": [
|
||||||
|
|||||||
+360
-140
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"rows": 2,
|
"rows": 3,
|
||||||
"cols": 5,
|
"cols": 7,
|
||||||
"grid": [],
|
"grid": [],
|
||||||
"positions": [
|
"positions": [
|
||||||
{
|
{
|
||||||
@@ -8,9 +8,9 @@
|
|||||||
"col": 0,
|
"col": 0,
|
||||||
"side": "front",
|
"side": "front",
|
||||||
"coords": [
|
"coords": [
|
||||||
0.5391402360519819,
|
0.726789462066099,
|
||||||
-1.3221212932804989,
|
0.38329959318460166,
|
||||||
-0.04968159116162075
|
0.023383889548769105
|
||||||
],
|
],
|
||||||
"poses": []
|
"poses": []
|
||||||
},
|
},
|
||||||
@@ -19,9 +19,9 @@
|
|||||||
"col": 1,
|
"col": 1,
|
||||||
"side": "front",
|
"side": "front",
|
||||||
"coords": [
|
"coords": [
|
||||||
1.1801154538454173,
|
1.5997282224959652,
|
||||||
-1.3641834306281595,
|
0.3969445083875386,
|
||||||
-0.0384636372066124
|
0.021611522117307245
|
||||||
],
|
],
|
||||||
"poses": []
|
"poses": []
|
||||||
},
|
},
|
||||||
@@ -30,9 +30,9 @@
|
|||||||
"col": 1,
|
"col": 1,
|
||||||
"side": "back",
|
"side": "back",
|
||||||
"coords": [
|
"coords": [
|
||||||
1.3273254588744863,
|
1.5365709266996668,
|
||||||
-3.5287940020200854,
|
-1.5897806027940793,
|
||||||
-3.11993523836094
|
-3.138003565212702
|
||||||
],
|
],
|
||||||
"poses": []
|
"poses": []
|
||||||
},
|
},
|
||||||
@@ -41,108 +41,9 @@
|
|||||||
"col": 0,
|
"col": 0,
|
||||||
"side": "back",
|
"side": "back",
|
||||||
"coords": [
|
"coords": [
|
||||||
0.6499623251724095,
|
0.7250933954217442,
|
||||||
-3.634895898964233,
|
-1.585626974855502,
|
||||||
-3.06371982741706
|
3.1407193246894285
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"row": 0,
|
|
||||||
"col": 2,
|
|
||||||
"side": "front",
|
|
||||||
"coords": [
|
|
||||||
1.9780660285152205,
|
|
||||||
-1.4118225222055494,
|
|
||||||
-0.03933461738640764
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"row": 0,
|
|
||||||
"col": 3,
|
|
||||||
"side": "front",
|
|
||||||
"coords": [
|
|
||||||
2.783104887196572,
|
|
||||||
-1.4531680360293173,
|
|
||||||
-0.005407493209801511
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"row": 0,
|
|
||||||
"col": 4,
|
|
||||||
"side": "front",
|
|
||||||
"coords": [
|
|
||||||
3.4135017183966694,
|
|
||||||
-1.463517938299615,
|
|
||||||
-0.0022379727318056074
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"row": 1,
|
|
||||||
"col": 4,
|
|
||||||
"side": "back",
|
|
||||||
"coords": [
|
|
||||||
3.595502564320599,
|
|
||||||
-3.5861571623928663,
|
|
||||||
3.105599537556842
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"row": 1,
|
|
||||||
"col": 4,
|
|
||||||
"side": "front",
|
|
||||||
"coords": [
|
|
||||||
3.595502564320599,
|
|
||||||
-3.5861571623928663,
|
|
||||||
3.105599537556842
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"row": 1,
|
|
||||||
"col": 3,
|
|
||||||
"side": "back",
|
|
||||||
"coords": [
|
|
||||||
2.8436692518324937,
|
|
||||||
-3.5087893361886504,
|
|
||||||
-3.0640151322957476
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"row": 1,
|
|
||||||
"col": 3,
|
|
||||||
"side": "front",
|
|
||||||
"coords": [
|
|
||||||
2.8436692518324937,
|
|
||||||
-3.5087893361886504,
|
|
||||||
-3.0640151322957476
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"row": 1,
|
|
||||||
"col": 2,
|
|
||||||
"side": "back",
|
|
||||||
"coords": [
|
|
||||||
2.0238357078548397,
|
|
||||||
-3.519588818855445,
|
|
||||||
-3.0949553553741684
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"row": 1,
|
|
||||||
"col": 2,
|
|
||||||
"side": "front",
|
|
||||||
"coords": [
|
|
||||||
2.0238357078548397,
|
|
||||||
-3.519588818855445,
|
|
||||||
-3.0949553553741684
|
|
||||||
],
|
],
|
||||||
"poses": []
|
"poses": []
|
||||||
},
|
},
|
||||||
@@ -151,9 +52,9 @@
|
|||||||
"col": 1,
|
"col": 1,
|
||||||
"side": "front",
|
"side": "front",
|
||||||
"coords": [
|
"coords": [
|
||||||
1.3273254588744863,
|
1.5365709266996668,
|
||||||
-3.5287940020200854,
|
-1.5897806027940793,
|
||||||
-3.11993523836094
|
-3.138003565212702
|
||||||
],
|
],
|
||||||
"poses": []
|
"poses": []
|
||||||
},
|
},
|
||||||
@@ -162,9 +63,9 @@
|
|||||||
"col": 0,
|
"col": 0,
|
||||||
"side": "front",
|
"side": "front",
|
||||||
"coords": [
|
"coords": [
|
||||||
0.6499623251724095,
|
0.7250933954217442,
|
||||||
-3.634895898964233,
|
-1.585626974855502,
|
||||||
-3.06371982741706
|
3.1407193246894285
|
||||||
],
|
],
|
||||||
"poses": []
|
"poses": []
|
||||||
},
|
},
|
||||||
@@ -173,9 +74,9 @@
|
|||||||
"col": 0,
|
"col": 0,
|
||||||
"side": "back",
|
"side": "back",
|
||||||
"coords": [
|
"coords": [
|
||||||
0.39025594509020667,
|
0.695891857743624,
|
||||||
-5.593393651151741,
|
-3.6093540626907155,
|
||||||
-0.09001000079607593
|
-0.01891669546737457
|
||||||
],
|
],
|
||||||
"poses": []
|
"poses": []
|
||||||
},
|
},
|
||||||
@@ -184,9 +85,196 @@
|
|||||||
"col": 1,
|
"col": 1,
|
||||||
"side": "back",
|
"side": "back",
|
||||||
"coords": [
|
"coords": [
|
||||||
0.9989880876134289,
|
1.7054640840200619,
|
||||||
-5.633047903271201,
|
-3.6172190671922944,
|
||||||
-0.08518177305398167
|
0.04050928996758301
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 0,
|
||||||
|
"col": 2,
|
||||||
|
"side": "front",
|
||||||
|
"coords": [
|
||||||
|
2.569630979384912,
|
||||||
|
0.39887714413011477,
|
||||||
|
0.013956327040945097
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 0,
|
||||||
|
"col": 3,
|
||||||
|
"side": "front",
|
||||||
|
"coords": [
|
||||||
|
3.5131599402572933,
|
||||||
|
0.3616416504697895,
|
||||||
|
0.0177534721641621
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 0,
|
||||||
|
"col": 4,
|
||||||
|
"side": "front",
|
||||||
|
"coords": [
|
||||||
|
4.385626456624971,
|
||||||
|
0.37358124345384475,
|
||||||
|
0.014464186351950986
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 0,
|
||||||
|
"col": 5,
|
||||||
|
"side": "front",
|
||||||
|
"coords": [
|
||||||
|
5.286651848873122,
|
||||||
|
0.36270375923170595,
|
||||||
|
-0.02478120105661721
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 0,
|
||||||
|
"col": 6,
|
||||||
|
"side": "front",
|
||||||
|
"coords": [
|
||||||
|
6.301663107708812,
|
||||||
|
0.35009837193686855,
|
||||||
|
0.05028809910702322
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 1,
|
||||||
|
"col": 6,
|
||||||
|
"side": "back",
|
||||||
|
"coords": [
|
||||||
|
6.302211902696101,
|
||||||
|
-1.6741865723108142,
|
||||||
|
-3.141294889035836
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 1,
|
||||||
|
"col": 6,
|
||||||
|
"side": "front",
|
||||||
|
"coords": [
|
||||||
|
6.302211902696101,
|
||||||
|
-1.6741865723108142,
|
||||||
|
-3.141294889035836
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 1,
|
||||||
|
"col": 5,
|
||||||
|
"side": "back",
|
||||||
|
"coords": [
|
||||||
|
5.385423949389957,
|
||||||
|
-1.6569851054137088,
|
||||||
|
3.114584306608913
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 1,
|
||||||
|
"col": 5,
|
||||||
|
"side": "front",
|
||||||
|
"coords": [
|
||||||
|
5.385423949389957,
|
||||||
|
-1.6569851054137088,
|
||||||
|
3.114584306608913
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 1,
|
||||||
|
"col": 4,
|
||||||
|
"side": "back",
|
||||||
|
"coords": [
|
||||||
|
4.520056315813734,
|
||||||
|
-1.6370730446353792,
|
||||||
|
3.12134578550089
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 1,
|
||||||
|
"col": 4,
|
||||||
|
"side": "front",
|
||||||
|
"coords": [
|
||||||
|
4.520056315813734,
|
||||||
|
-1.6370730446353792,
|
||||||
|
3.12134578550089
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 1,
|
||||||
|
"col": 3,
|
||||||
|
"side": "back",
|
||||||
|
"coords": [
|
||||||
|
3.600184234659078,
|
||||||
|
-1.6299160740114962,
|
||||||
|
-3.127182700330921
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 1,
|
||||||
|
"col": 3,
|
||||||
|
"side": "front",
|
||||||
|
"coords": [
|
||||||
|
3.600184234659078,
|
||||||
|
-1.6299160740114962,
|
||||||
|
-3.127182700330921
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 1,
|
||||||
|
"col": 2,
|
||||||
|
"side": "back",
|
||||||
|
"coords": [
|
||||||
|
2.5627723519921295,
|
||||||
|
-1.606403204776104,
|
||||||
|
3.1392697865149666
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 1,
|
||||||
|
"col": 2,
|
||||||
|
"side": "front",
|
||||||
|
"coords": [
|
||||||
|
2.5627723519921295,
|
||||||
|
-1.606403204776104,
|
||||||
|
3.1392697865149666
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 2,
|
||||||
|
"col": 0,
|
||||||
|
"side": "front",
|
||||||
|
"coords": [
|
||||||
|
0.695891857743624,
|
||||||
|
-3.6093540626907155,
|
||||||
|
-0.01891669546737457
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 2,
|
||||||
|
"col": 1,
|
||||||
|
"side": "front",
|
||||||
|
"coords": [
|
||||||
|
1.7054640840200619,
|
||||||
|
-3.6172190671922944,
|
||||||
|
0.04050928996758301
|
||||||
],
|
],
|
||||||
"poses": []
|
"poses": []
|
||||||
},
|
},
|
||||||
@@ -195,9 +283,20 @@
|
|||||||
"col": 2,
|
"col": 2,
|
||||||
"side": "back",
|
"side": "back",
|
||||||
"coords": [
|
"coords": [
|
||||||
1.7493440267548326,
|
2.49138966620064,
|
||||||
-5.7036971258959746,
|
-3.6258193640543435,
|
||||||
-0.10505541857885684
|
0.011734020269766346
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 2,
|
||||||
|
"col": 2,
|
||||||
|
"side": "front",
|
||||||
|
"coords": [
|
||||||
|
2.49138966620064,
|
||||||
|
-3.6258193640543435,
|
||||||
|
0.011734020269766346
|
||||||
],
|
],
|
||||||
"poses": []
|
"poses": []
|
||||||
},
|
},
|
||||||
@@ -206,9 +305,20 @@
|
|||||||
"col": 3,
|
"col": 3,
|
||||||
"side": "back",
|
"side": "back",
|
||||||
"coords": [
|
"coords": [
|
||||||
2.407336669431407,
|
3.384299605055195,
|
||||||
-5.76958512207572,
|
-3.633059580331103,
|
||||||
-0.10251877401062247
|
0.00825489611393585
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 2,
|
||||||
|
"col": 3,
|
||||||
|
"side": "front",
|
||||||
|
"coords": [
|
||||||
|
3.384299605055195,
|
||||||
|
-3.633059580331103,
|
||||||
|
0.00825489611393585
|
||||||
],
|
],
|
||||||
"poses": []
|
"poses": []
|
||||||
},
|
},
|
||||||
@@ -217,19 +327,129 @@
|
|||||||
"col": 4,
|
"col": 4,
|
||||||
"side": "back",
|
"side": "back",
|
||||||
"coords": [
|
"coords": [
|
||||||
3.132062476985721,
|
4.499614777619532,
|
||||||
-5.850166571217611,
|
-3.6568143703418405,
|
||||||
-0.09127007182804729
|
0.006128126167414207
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 2,
|
||||||
|
"col": 4,
|
||||||
|
"side": "front",
|
||||||
|
"coords": [
|
||||||
|
4.499614777619532,
|
||||||
|
-3.6568143703418405,
|
||||||
|
0.006128126167414207
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 2,
|
||||||
|
"col": 5,
|
||||||
|
"side": "back",
|
||||||
|
"coords": [
|
||||||
|
5.358194832629194,
|
||||||
|
-3.6555884207351923,
|
||||||
|
0.00220732555627522
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 2,
|
||||||
|
"col": 5,
|
||||||
|
"side": "front",
|
||||||
|
"coords": [
|
||||||
|
5.358194832629194,
|
||||||
|
-3.6555884207351923,
|
||||||
|
0.00220732555627522
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 2,
|
||||||
|
"col": 6,
|
||||||
|
"side": "back",
|
||||||
|
"coords": [
|
||||||
|
6.186931240051006,
|
||||||
|
-3.660069561737178,
|
||||||
|
-0.004740651362042846
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 2,
|
||||||
|
"col": 6,
|
||||||
|
"side": "front",
|
||||||
|
"coords": [
|
||||||
|
6.186931240051006,
|
||||||
|
-3.660069561737178,
|
||||||
|
-0.004740651362042846
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 3,
|
||||||
|
"col": 4,
|
||||||
|
"side": "back",
|
||||||
|
"coords": [
|
||||||
|
4.437106056578727,
|
||||||
|
-5.675385129487837,
|
||||||
|
3.113166940596223
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 3,
|
||||||
|
"col": 3,
|
||||||
|
"side": "back",
|
||||||
|
"coords": [
|
||||||
|
3.4577008440661285,
|
||||||
|
-5.703184532839961,
|
||||||
|
-3.109685273113602
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 3,
|
||||||
|
"col": 2,
|
||||||
|
"side": "back",
|
||||||
|
"coords": [
|
||||||
|
2.3341924779097645,
|
||||||
|
-5.623728684341702,
|
||||||
|
-3.095440697434253
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 3,
|
||||||
|
"col": 1,
|
||||||
|
"side": "back",
|
||||||
|
"coords": [
|
||||||
|
1.6126711501886855,
|
||||||
|
-5.64506932868408,
|
||||||
|
-3.0994397969930265
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"row": 3,
|
||||||
|
"col": 0,
|
||||||
|
"side": "back",
|
||||||
|
"coords": [
|
||||||
|
0.6321940488248773,
|
||||||
|
-5.633649464598426,
|
||||||
|
3.129000825841382
|
||||||
],
|
],
|
||||||
"poses": []
|
"poses": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"arm_initial_pose": [
|
"arm_initial_pose": [
|
||||||
-90.333323,
|
-89.999795,
|
||||||
-90.079952,
|
-89.999946,
|
||||||
0.160037,
|
-0.000131,
|
||||||
-90.571318,
|
-90.00001,
|
||||||
0.093654,
|
4.1e-05,
|
||||||
22.232898
|
0.000116
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -9,12 +9,12 @@
|
|||||||
"name": "front_1",
|
"name": "front_1",
|
||||||
"photo_type": "front",
|
"photo_type": "front",
|
||||||
"arm_angles": [
|
"arm_angles": [
|
||||||
-93.586541,
|
-81.796775,
|
||||||
-184.343305,
|
-85.406752,
|
||||||
50.583239,
|
-5.803223,
|
||||||
-38.326674,
|
-109.799747,
|
||||||
-85.153333,
|
91.66639,
|
||||||
20.399989
|
2.446712
|
||||||
],
|
],
|
||||||
"speed": 500,
|
"speed": 500,
|
||||||
"description": ""
|
"description": ""
|
||||||
@@ -24,12 +24,12 @@
|
|||||||
"name": "back_1",
|
"name": "back_1",
|
||||||
"photo_type": "back",
|
"photo_type": "back",
|
||||||
"arm_angles": [
|
"arm_angles": [
|
||||||
15.860045,
|
-81.796823,
|
||||||
-161.133416,
|
-85.406717,
|
||||||
137.999016,
|
-5.803284,
|
||||||
-161.996719,
|
-109.799953,
|
||||||
168.000989,
|
91.666459,
|
||||||
15.653445
|
2.44676
|
||||||
],
|
],
|
||||||
"speed": 500,
|
"speed": 500,
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
"id": "qr_1779278140334",
|
"id": "qr_1779278140334",
|
||||||
"name": "二维码1",
|
"name": "二维码1",
|
||||||
"joint_angles": [
|
"joint_angles": [
|
||||||
-89.796645,
|
89.999979,
|
||||||
-2.013175,
|
-0.000118,
|
||||||
-87.176721,
|
-120.09949,
|
||||||
-82.49663,
|
-30,
|
||||||
-93.323403,
|
-105,
|
||||||
20.399941
|
0
|
||||||
],
|
],
|
||||||
"qr_value": "BG042110276",
|
"qr_value": "BG042110276",
|
||||||
"model_id": ""
|
"model_id": ""
|
||||||
|
|||||||
@@ -381,8 +381,9 @@ createApp({
|
|||||||
} catch (e) { alert('导航失败: ' + e.message) }
|
} catch (e) { alert('导航失败: ' + e.message) }
|
||||||
},
|
},
|
||||||
async goToOrigin() {
|
async goToOrigin() {
|
||||||
if (!confirm('确认导航到原点 (0, 0, 0)?')) return
|
if (!confirm('确认先复原机械臂,再导航到原点 (0, 0, 0)?')) return
|
||||||
try {
|
try {
|
||||||
|
this.mapMsg = '正在复原机械臂并发送原点导航...'
|
||||||
const res = await fetch(API + '/api/navigate/to', {
|
const res = await fetch(API + '/api/navigate/to', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
@@ -390,7 +391,7 @@ createApp({
|
|||||||
})
|
})
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
if (data.ok) {
|
if (data.ok) {
|
||||||
this.mapMsg = '✅ 已发送导航到原点'
|
this.mapMsg = '✅ ' + (data.message || '已发送导航到原点')
|
||||||
} else {
|
} else {
|
||||||
this.mapMsg = '❌ ' + (data.error || '导航失败')
|
this.mapMsg = '❌ ' + (data.error || '导航失败')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -414,6 +414,14 @@ class MissionExecutorV3:
|
|||||||
model_name = self._lookup_model(qr_value)
|
model_name = self._lookup_model(qr_value)
|
||||||
self._log(f" 🏷️ 机型: {model_name}")
|
self._log(f" 🏷️ 机型: {model_name}")
|
||||||
|
|
||||||
|
if qr_value and opt_arm_init and has_arm_pose and opt_agv_move and not self._stop.is_set():
|
||||||
|
self._log(" 🦾 扫码完成,恢复机械臂初始姿态")
|
||||||
|
try:
|
||||||
|
self.arm_client.set_angles(arm_initial_pose, speed=self.arm_speed)
|
||||||
|
self._wait_arm_ready(arm_initial_pose)
|
||||||
|
except Exception as e:
|
||||||
|
self._log(f" ⚠️ 机械臂复位失败: {e}")
|
||||||
|
|
||||||
if opt_front_photo and not self._stop.is_set():
|
if opt_front_photo and not self._stop.is_set():
|
||||||
model = self._find_model(models, model_name)
|
model = self._find_model(models, model_name)
|
||||||
if model:
|
if model:
|
||||||
@@ -642,7 +650,7 @@ class MissionExecutorV3:
|
|||||||
self._log("↪️ 调用设置页同款接口返回原点")
|
self._log("↪️ 调用设置页同款接口返回原点")
|
||||||
resp = requests.post(
|
resp = requests.post(
|
||||||
"http://127.0.0.1:5000/api/navigate/to",
|
"http://127.0.0.1:5000/api/navigate/to",
|
||||||
json={"x": 0, "y": 0, "yaw": 0},
|
json={"x": 0, "y": 0, "yaw": 0, "restore_arm": False},
|
||||||
timeout=8,
|
timeout=8,
|
||||||
)
|
)
|
||||||
data = resp.json() if resp.content else {}
|
data = resp.json() if resp.content else {}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import type { ActivityItem, CameraInfo, CustomsDeclaration, InspectionIssue, Ins
|
|||||||
|
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
const { TextArea } = Input;
|
const { TextArea } = Input;
|
||||||
|
const LOG_AUTO_SCROLL_THRESHOLD = 48;
|
||||||
|
|
||||||
interface ProgressItem extends InspectionItem {
|
interface ProgressItem extends InspectionItem {
|
||||||
currentInspected: number;
|
currentInspected: number;
|
||||||
@@ -78,7 +79,8 @@ function InspectionContent() {
|
|||||||
const [operationLoading, setOperationLoading] = useState(false);
|
const [operationLoading, setOperationLoading] = useState(false);
|
||||||
const [messageApi, contextHolder] = message.useMessage();
|
const [messageApi, contextHolder] = message.useMessage();
|
||||||
const { token } = theme.useToken();
|
const { token } = theme.useToken();
|
||||||
const logsEndRef = useRef<HTMLDivElement>(null);
|
const logsContainerRef = useRef<HTMLDivElement>(null);
|
||||||
|
const [isUserNearBottom, setIsUserNearBottom] = useState(true);
|
||||||
|
|
||||||
const refreshRuntime = async () => {
|
const refreshRuntime = async () => {
|
||||||
const [missionState, currentInspection, missionLogs, nextIssues] = await Promise.all([
|
const [missionState, currentInspection, missionLogs, nextIssues] = await Promise.all([
|
||||||
@@ -231,8 +233,19 @@ function InspectionContent() {
|
|||||||
}, [setInspection]);
|
}, [setInspection]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
logsEndRef.current?.scrollIntoView({ behavior: 'smooth' });
|
const container = logsContainerRef.current;
|
||||||
}, [logs]);
|
if (container && isUserNearBottom) {
|
||||||
|
container.scrollTop = container.scrollHeight;
|
||||||
|
}
|
||||||
|
}, [logs, isUserNearBottom]);
|
||||||
|
|
||||||
|
const handleLogsScroll = () => {
|
||||||
|
const container = logsContainerRef.current;
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
const distanceToBottom = container.scrollHeight - container.scrollTop - container.clientHeight;
|
||||||
|
setIsUserNearBottom(distanceToBottom <= LOG_AUTO_SCROLL_THRESHOLD);
|
||||||
|
};
|
||||||
|
|
||||||
const calculateTotalProgress = () => {
|
const calculateTotalProgress = () => {
|
||||||
if (!progressData.length) return 0;
|
if (!progressData.length) return 0;
|
||||||
@@ -524,7 +537,7 @@ function InspectionContent() {
|
|||||||
style={{ flex: 3, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}
|
style={{ flex: 3, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}
|
||||||
styles={{ body: { padding: 12, flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0, background: token.colorFillQuaternary } }}
|
styles={{ body: { padding: 12, flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0, background: token.colorFillQuaternary } }}
|
||||||
>
|
>
|
||||||
<div style={{ flex: 1, overflowY: 'auto', paddingRight: 8 }}>
|
<div ref={logsContainerRef} onScroll={handleLogsScroll} style={{ flex: 1, overflowY: 'auto', paddingRight: 8 }}>
|
||||||
{logs.length > 0 ? (
|
{logs.length > 0 ? (
|
||||||
<Timeline
|
<Timeline
|
||||||
items={logs.map((item) => ({
|
items={logs.map((item) => ({
|
||||||
@@ -540,7 +553,6 @@ function InspectionContent() {
|
|||||||
) : (
|
) : (
|
||||||
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无日志" style={{ margin: '20px 0' }} />
|
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无日志" style={{ margin: '20px 0' }} />
|
||||||
)}
|
)}
|
||||||
<div ref={logsEndRef} />
|
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
|
|||||||
Reference in New Issue
Block a user