fix: 更新机器人信息类型,添加告警和故障状态,优化机器人状态获取逻辑,调整主题颜色配置以支持不同状态

This commit is contained in:
xudan 2025-07-07 17:00:21 +08:00
parent d6aabaf6ed
commit b0f7620626
6 changed files with 49 additions and 10 deletions

View File

@ -48,7 +48,7 @@ export interface MapAreaInfo {
//#endregion //#endregion
//#region 机器人 //#region 机器人
export type MapRobotInfo = Pick<RobotRealtimeInfo, 'type' | 'active' | 'path'>; export type MapRobotInfo = Pick<RobotRealtimeInfo, 'type' | 'active' | 'path' | 'isWaring' | 'isFault'>;
//#endregion //#endregion
export type Point = Record<'x' | 'y', number>; export type Point = Record<'x' | 'y', number>;

View File

@ -42,4 +42,6 @@ export interface RobotRealtimeInfo extends RobotInfo {
active?: boolean; // 是否运行 active?: boolean; // 是否运行
angle?: number; // 旋转角度 angle?: number; // 旋转角度
path?: Array<Point>; // 规划路径 path?: Array<Point>; // 规划路径
isWaring?: boolean; // 是否告警
isFault?: boolean; // 是否故障
} }

View File

@ -35,6 +35,12 @@
"robot": { "robot": {
"stroke": "#01FDAF99", "stroke": "#01FDAF99",
"fill": "#01FAAD33", "fill": "#01FAAD33",
"line": "#01fdaf" "line": "#01fdaf",
"stroke-normal": "#01FDAF99",
"fill-normal": "#01FAAD33",
"stroke-warning": "#FF851B99",
"fill-warning": "#FF851B33",
"stroke-fault": "#FF4D4F99",
"fill-fault": "#FF4D4F33"
} }
} }

View File

@ -35,6 +35,12 @@
"robot": { "robot": {
"stroke": "#01FDAF99", "stroke": "#01FDAF99",
"fill": "#01FAAD33", "fill": "#01FAAD33",
"line": "#01fdaf" "line": "#01fdaf",
"stroke-normal": "#01FDAF99",
"fill-normal": "#01FAAD33",
"stroke-warning": "#FF851B99",
"fill-warning": "#FF851B33",
"stroke-fault": "#FF4D4F99",
"fill-fault": "#FF4D4F33"
} }
} }

View File

@ -33,13 +33,13 @@ const monitorScene = async () => {
const ws = isMonitorMode.value ? await monitorRealSceneById(props.sid) : await monitorSceneById(props.sid); const ws = isMonitorMode.value ? await monitorRealSceneById(props.sid) : await monitorSceneById(props.sid);
if (isNil(ws)) return; if (isNil(ws)) return;
ws.onmessage = (e) => { ws.onmessage = (e) => {
const { id, x, y, active, angle, path, ...rest } = <RobotRealtimeInfo>JSON.parse(e.data || '{}'); const { id, x, y, active, angle, path, isWaring, isFault, ...rest } = <RobotRealtimeInfo>JSON.parse(e.data || '{}');
if (!editor.value?.checkRobotById(id)) return; if (!editor.value?.checkRobotById(id)) return;
editor.value?.updateRobot(id, rest); editor.value?.updateRobot(id, rest);
if (isNil(x) || isNil(y)) { if (isNil(x) || isNil(y)) {
editor.value.updatePen(id, { visible: false }); editor.value.updatePen(id, { visible: false });
} else { } else {
editor.value.refreshRobot(id, { x, y, active, angle, path }); editor.value.refreshRobot(id, { x, y, active, angle, path, isWaring, isFault });
} }
}; };
client.value = ws; client.value = ws;

View File

@ -574,14 +574,14 @@ export class EditorService extends Meta2d {
const { rotate: or, robot } = pen ?? {}; const { rotate: or, robot } = pen ?? {};
if (!robot?.type) return; if (!robot?.type) return;
const { x: ox, y: oy } = this.getPenRect(pen!); const { x: ox, y: oy } = this.getPenRect(pen!);
const { x: cx = 37, y: cy = 37, active, angle, path: points } = info; const { x: cx = 37, y: cy = 37, active, angle, path: points, isWaring, isFault } = info;
const x = cx - 37; const x = cx - 37;
const y = cy - 37; const y = cy - 37;
const rotate = angle ?? or; const rotate = angle ?? or;
const path = const path =
points?.map((p) => ({ x: p.x - cx, y: p.y - cy })) ?? points?.map((p) => ({ x: p.x - cx, y: p.y - cy })) ??
robot.path?.map((p) => ({ x: p.x + ox! - x, y: p.y + oy! - y })); robot.path?.map((p) => ({ x: p.x + ox! - x, y: p.y + oy! - y }));
const o = { ...robot, ...omitBy({ active, path }, isNil) }; const o = { ...robot, ...omitBy({ active, path, isWaring, isFault }, isNil) };
if (isNil(active)) { if (isNil(active)) {
this.setValue({ id, x, y, rotate, robot: o, visible: true }, { render: true, history: false, doEvent: false }); this.setValue({ id, x, y, rotate, robot: o, visible: true }, { render: true, history: false, doEvent: false });
} else { } else {
@ -1133,6 +1133,27 @@ function drawArea(ctx: CanvasRenderingContext2D, pen: MapPen): void {
ctx.restore(); ctx.restore();
} }
/**
*
* @param isWaring
* @param isFault
* @returns : 'fault' | 'warning' | 'normal'
*
*
* - isWaring=true, isFault=true
* - isWaring=false, isFault=true
* - isWaring=true, isFault=false
* - isWaring=false, isFault=false
*/
function getRobotStatus(isWaring?: boolean, isFault?: boolean): 'fault' | 'warning' | 'normal' {
// 只要 isFault 为 true无论 isWaring 是什么,都是故障状态
if (isFault) return 'fault';
// 如果 isFault 为 false 但 isWaring 为 true则是告警状态
if (isWaring) return 'warning';
// 两者都为 false 时,为正常状态
return 'normal';
}
/** /**
* *
* @param ctx Canvas 2D绘制上下文 * @param ctx Canvas 2D绘制上下文
@ -1142,16 +1163,20 @@ function drawRobot(ctx: CanvasRenderingContext2D, pen: MapPen): void {
const theme = sTheme.editor; const theme = sTheme.editor;
const { lineWidth: s = 1 } = pen.calculative ?? {}; const { lineWidth: s = 1 } = pen.calculative ?? {};
const { x = 0, y = 0, width: w = 0, height: h = 0, rotate: deg = 0 } = pen.calculative?.worldRect ?? {}; const { x = 0, y = 0, width: w = 0, height: h = 0, rotate: deg = 0 } = pen.calculative?.worldRect ?? {};
const { active, path } = pen.robot ?? {}; const { active, path, isWaring, isFault } = pen.robot ?? {};
if (!active) return; if (!active) return;
// 根据机器人状态获取颜色
const status = getRobotStatus(isWaring, isFault);
const ox = x + w / 2; const ox = x + w / 2;
const oy = y + h / 2; const oy = y + h / 2;
ctx.save(); ctx.save();
ctx.ellipse(ox, oy, w / 2, h / 2, 0, 0, Math.PI * 2); ctx.ellipse(ox, oy, w / 2, h / 2, 0, 0, Math.PI * 2);
ctx.fillStyle = get(theme, 'robot.fill') ?? ''; ctx.fillStyle = get(theme, `robot.fill-${status}`) ?? get(theme, 'robot.fill') ?? '';
ctx.fill(); ctx.fill();
ctx.strokeStyle = get(theme, 'robot.stroke') ?? ''; ctx.strokeStyle = get(theme, `robot.stroke-${status}`) ?? get(theme, 'robot.stroke') ?? '';
ctx.stroke(); ctx.stroke();
if (path?.length) { if (path?.length) {
ctx.strokeStyle = get(theme, 'robot.line') ?? ''; ctx.strokeStyle = get(theme, 'robot.line') ?? '';