inspection-host-computer/server/index.js

411 lines
8.9 KiB
JavaScript
Raw Normal View History

2026-06-26 10:51:01 +08:00
// server/index.js
import express from 'express'
import cors from 'cors'
2026-06-29 17:29:36 +08:00
import path from 'path';
2026-06-26 10:51:01 +08:00
2026-07-02 16:21:38 +08:00
import 'dotenv/config';
import { createAGVGrpcClient, createARMGrpcClient, __dirname } from './grpcClient.js';
2026-06-26 10:51:01 +08:00
const app = express()
app.use(express.static(path.join(__dirname, '../dist')));
app.use(cors())
app.use(express.json())
// 获取机器人当前地图名称
app.post('/api/agv/getCurrentMapName', async (req, res) => {
const request = {
header: {
device_id: req.body.device_id || 'agv_src1100'
}
};
2026-07-02 16:21:38 +08:00
const grpcClient = createAGVGrpcClient(req.body.ip)
2026-06-26 10:51:01 +08:00
const resp = await new Promise((resolve, reject) => {
grpcClient.getMapStatus(request, (err, res) => {
if (err) {
resolve({
code: 500,
data: `grpc服务端错误`
});
} else {
resolve({
code: 200,
data: res.status
});
}
});
})
if (resp.code === 200) {
res.json(resp)
} else {
res.status(500).json({ error: 'grpc服务端错误' })
}
})
// 获取机器人当前地图名称
app.post('/api/agv/getCurrentMap', async (req, res) => {
2026-07-02 16:21:38 +08:00
const grpcClient = createAGVGrpcClient(req.body.ip)
2026-06-26 10:51:01 +08:00
const request = {
header: {
device_id: req.body.device_id || 'agv_src1100'
},
data: {
map_name: req.body.mapName
}
};
const resp = await new Promise((resolve, reject) => {
grpcClient.RobotConfigDownloadMap(request, (err, res) => {
if (err) {
resolve({
code: 500,
data: `grpc服务端错误`
});
} else {
resolve({
code: 200,
data: res.status
});
}
});
})
if (resp.code === 200) {
res.json(resp)
} else {
res.status(500).json({ error: 'grpc服务端错误' })
}
})
2026-07-02 16:21:38 +08:00
// 获取机器人状态
2026-06-26 10:51:01 +08:00
app.post('/api/agv/getRobotState', async (req, res) => {
const request = {
header: {
device_id: req.body.device_id || 'agv_src1100'
}
};
2026-07-02 16:21:38 +08:00
const grpcClient = createAGVGrpcClient(req.body.ip)
2026-06-26 10:51:01 +08:00
const response = await new Promise((resolve, reject) => {
grpcClient.GetRobotLocation(request, (err, res) => {
if (err) {
resolve({
code: 500,
data: `grpc服务端错误`
});
} else {
resolve({
code: 200,
data: res.status
});
}
})
})
const resp = await new Promise((resolve, reject) => {
grpcClient.GetBatteryStatus(request, (err, res) => {
if (err) {
resolve({
code: 500,
data: `grpc服务端错误`
});
} else {
resolve({
code: 200,
data: res.status
});
}
});
})
if (response.code === 200 && resp.code ===200) {
res.json({
code: 200,
data: {
x: response.data.x,
y: response.data.y,
angle: response.data.angle,
confidence: response.data.confidence,
batteryLevel: resp.data.battery_level,
batteryTemp: resp.data.battery_temp,
charging: resp.data.charging,
voltage: resp.data.voltage
}
})
} else {
res.status(500).json({ error: 'grpc服务端错误' })
}
})
2026-07-02 16:21:38 +08:00
// 机器人运动控制
2026-06-26 10:51:01 +08:00
app.post('/api/agv/moveRobot', async (req, res) => {
2026-07-02 16:21:38 +08:00
const grpcClient = createAGVGrpcClient(req.body.ip)
2026-06-26 10:51:01 +08:00
const request = {
header: {
device_id: req.body.device_id || 'agv_src1100'
},
data: {
vx: req.body.vx,
vy: req.body.vy,
w: req.body.w,
duration: req.body.duration
}
};
const resp = await new Promise((resolve, reject) => {
grpcClient.RobotMotionControl(request, (err, res) => {
if (err) {
resolve({
code: 500,
data: `grpc服务端错误`
});
} else {
resolve({
code: 200,
data: res.status
});
}
});
})
if (resp.code === 200) {
res.json({
code: 200,
data: resp
})
} else {
res.status(500).json({ error: 'grpc服务端错误' })
}
})
2026-07-02 16:21:38 +08:00
// 机器人停止运动
2026-06-26 10:51:01 +08:00
app.post('/api/agv/stopRobot', async (req, res) => {
2026-07-02 16:21:38 +08:00
const grpcClient = createAGVGrpcClient(req.body.ip)
2026-06-26 10:51:01 +08:00
const request = {
header: {
device_id: req.body.device_id || 'agv_src1100'
}
};
const resp = await new Promise((resolve, reject) => {
grpcClient.RobotControlStop(request, (err, res) => {
if (err) {
resolve({
code: 500,
data: `grpc服务端错误`
});
} else {
resolve({
code: 200,
data: res.status
});
}
});
})
if (resp.code === 200) {
res.json({
code: 200,
data: resp
})
} else {
res.status(500).json({ error: 'grpc服务端错误' })
}
})
2026-07-02 16:21:38 +08:00
// 获取机械臂末端位姿
app.post('/api/arm/getPose', async (req, res) => {
const request = {
header: {
device_id: req.body.deviceId || 'huayan_arm'
}
};
const grpcClient = createARMGrpcClient(req.body.ip)
const resp = await new Promise((resolve, reject) => {
grpcClient.getPose(request, (err, res) => {
if (err) {
resolve({
code: 500,
data: `grpc服务端错误`
});
} else {
resolve({
code: 200,
data: res.pose
});
}
});
})
if (resp.code === 200) {
res.json(resp)
} else {
res.status(500).json({ error: 'grpc服务端错误' })
}
})
// 获取机械臂节点状态
app.post('/api/arm/getJointState', async (req, res) => {
const request = {
header: {
device_id: req.body.deviceId || 'huayan_arm'
}
};
const grpcClient = createARMGrpcClient(req.body.ip)
const resp = await new Promise((resolve, reject) => {
grpcClient.getJointState(request, (err, res) => {
if (err) {
resolve({
code: 500,
data: `grpc服务端错误`
});
} else {
resolve({
code: 200,
data: res.state
});
}
});
})
if (resp.code === 200) {
res.json(resp)
} else {
res.status(500).json({ error: 'grpc服务端错误' })
}
})
// 机械臂关节运动
app.post('/api/arm/speedJ', async (req, res) => {
const request = {
header: {
device_id: req.body.deviceId || 'huayan_arm'
},
velocity: {
velocity: req.body.velocities
},
acceleration: req.body.acceleration,
duration: req.body.duration
};
const grpcClient = createARMGrpcClient(req.body.ip)
const resp = await new Promise((resolve, reject) => {
grpcClient.speedJ(request, (err, res) => {
if (err) {
resolve({
code: 500,
data: `grpc服务端错误`
});
} else {
resolve({
code: 200,
data: res
});
}
});
})
if (resp.code === 200) {
res.json(resp)
} else {
res.status(500).json({ error: 'grpc服务端错误' })
}
})
app.post('/api/arm/speedL', async (req, res) => {
const request = {
header: {
device_id: req.body.deviceId || 'huayan_arm'
},
velocity: req.body.velocity,
acceleration: req.body.acceleration,
duration: req.body.duration
};
const grpcClient = createARMGrpcClient(req.body.ip)
const resp = await new Promise((resolve, reject) => {
grpcClient.speedL(request, (err, res) => {
if (err) {
resolve({
code: 500,
data: `grpc服务端错误`
});
} else {
resolve({
code: 200,
data: res
});
}
});
})
if (resp.code === 200) {
res.json(resp)
} else {
res.status(500).json({ error: 'grpc服务端错误' })
}
})
// 机械臂停止运动
app.post('/api/arm/stopMotion', async (req, res) => {
const request = {
// header: {
device_id: req.body.deviceId || 'huayan_arm',
// },
};
const grpcClient = createARMGrpcClient(req.body.ip)
const resp = await new Promise((resolve, reject) => {
grpcClient.stopMotion(request, (err, res) => {
if (err) {
resolve({
code: 500,
data: `grpc服务端错误`
});
} else {
resolve({
code: 200,
data: res.success
});
}
});
})
if (resp.code === 200) {
res.json(resp)
} else {
res.status(500).json({ error: 'grpc服务端错误' })
}
})
2026-06-29 11:17:08 +08:00
const isProd = process.env.NODE_ENV === 'production';
const PORT = process.env.VITE_SERVICE_PORT || 3000;
// ============ 生产环境:托管 Vite 构建产物 ============
if (isProd) {
2026-06-29 17:29:36 +08:00
const distPath = path.resolve(__dirname, '../dist');
2026-06-29 11:17:08 +08:00
// 托管静态文件
app.use(express.static(distPath));
// SPA 回退:所有非 API 请求返回 index.html
2026-06-29 17:33:18 +08:00
app.get('/{*path}', (req, res) => {
2026-06-29 17:29:36 +08:00
res.sendFile(path.resolve(distPath, 'index.html'));
2026-06-29 11:17:08 +08:00
});
2026-06-29 17:33:18 +08:00
app.post('/{*path}', (req, res) => {
2026-06-29 17:29:36 +08:00
res.sendFile(path.resolve(distPath, 'index.html'));
2026-06-29 11:17:08 +08:00
});
}
// ========== 启动 =========
2026-06-26 10:51:01 +08:00
app.listen(PORT, () => {
console.log(`gRPC 桥接服务已启动: http://localhost:${PORT}`)
})