feat: 机械臂

This commit is contained in:
zhanghao 2026-07-10 13:44:07 +08:00
parent 98031a0dcc
commit 0e12299816
11 changed files with 539 additions and 995 deletions

2
.env
View File

@ -1,4 +1,4 @@
# VITE_AGV_DEVICE_ID = 'agv_src2200' # VITE_AGV_DEVICE_ID = 'src1100'
# VITE_ARM_DEVICE_ID = 'aubo_arm' # VITE_ARM_DEVICE_ID = 'aubo_arm'
# 机械臂IP 192.168.1.109:50052 # 机械臂IP 192.168.1.109:50052

View File

@ -11,8 +11,8 @@ app.use(express.static(path.join(__dirname, '../dist')));
app.use(cors()) app.use(cors())
app.use(express.json()) app.use(express.json())
// 获取机器人当前地图名称 // 获取agv运行时状态
app.post('/api/agv/getCurrentMapName', async (req, res) => { app.post('/api/agv/getRuntimeState', async (req, res) => {
const request = { const request = {
header: { header: {
device_id: req.body.deviceId || 'agv_src1100' device_id: req.body.deviceId || 'agv_src1100'
@ -22,7 +22,7 @@ app.post('/api/agv/getCurrentMapName', async (req, res) => {
const grpcClient = createAGVGrpcClient(req.body.ip) const grpcClient = createAGVGrpcClient(req.body.ip)
const resp = await new Promise((resolve, reject) => { const resp = await new Promise((resolve, reject) => {
grpcClient.getMapStatus(request, (err, res) => { grpcClient.getRuntimeState(request, (err, res) => {
if (err) { if (err) {
resolve({ resolve({
code: 500, code: 500,
@ -31,7 +31,7 @@ app.post('/api/agv/getCurrentMapName', async (req, res) => {
} else { } else {
resolve({ resolve({
code: 200, code: 200,
data: res.status data: res.state
}); });
} }
}); });
@ -44,20 +44,18 @@ app.post('/api/agv/getCurrentMapName', async (req, res) => {
} }
}) })
// 获取机器人当前地图名称 // 获取机器人当前地图
app.post('/api/agv/getCurrentMap', async (req, res) => { app.post('/api/agv/getCurrentMap', async (req, res) => {
const grpcClient = createAGVGrpcClient(req.body.ip) const grpcClient = createAGVGrpcClient(req.body.ip)
const request = { const request = {
header: { header: {
device_id: req.body.deviceId || 'agv_src1100' device_id: req.body.deviceId || 'agv_src1100'
}, },
data: { map_name: req.body.mapName
map_name: req.body.mapName
}
}; };
const resp = await new Promise((resolve, reject) => { const resp = await new Promise((resolve, reject) => {
grpcClient.RobotConfigDownloadMap(request, (err, res) => { grpcClient.downloadMap(request, (err, res) => {
if (err) { if (err) {
resolve({ resolve({
code: 500, code: 500,
@ -66,7 +64,7 @@ app.post('/api/agv/getCurrentMap', async (req, res) => {
} else { } else {
resolve({ resolve({
code: 200, code: 200,
data: res.status data: res.content
}); });
} }
}); });
@ -79,83 +77,22 @@ app.post('/api/agv/getCurrentMap', async (req, res) => {
} }
}) })
// 获取机器人状态
app.post('/api/agv/getRobotState', async (req, res) => {
const request = {
header: {
device_id: req.body.deviceId || 'agv_src1100'
}
};
const grpcClient = createAGVGrpcClient(req.body.ip)
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服务端错误' })
}
})
// 机器人运动控制 // 机器人运动控制
app.post('/api/agv/moveRobot', async (req, res) => { app.post('/api/agv/moveRobot', async (req, res) => {
const grpcClient = createAGVGrpcClient(req.body.ip) const grpcClient = setVelocity(req.body.ip)
const request = { const request = {
header: { header: {
device_id: req.body.deviceId || 'agv_src1100' device_id: req.body.deviceId || 'agv_src1100'
}, },
data: { velocity: {
vx: req.body.vx, vx: req.body.vx,
vy: req.body.vy, vy: req.body.vy,
w: req.body.w, vz: req.body.vz
duration: req.body.duration
} }
}; };
const resp = await new Promise((resolve, reject) => { const resp = await new Promise((resolve, reject) => {
grpcClient.RobotMotionControl(request, (err, res) => { grpcClient.setVelocity(request, (err, res) => {
if (err) { if (err) {
resolve({ resolve({
code: 500, code: 500,
@ -190,7 +127,7 @@ app.post('/api/agv/stopRobot', async (req, res) => {
}; };
const resp = await new Promise((resolve, reject) => { const resp = await new Promise((resolve, reject) => {
grpcClient.RobotControlStop(request, (err, res) => { grpcClient.stopVelocityControl(request, (err, res) => {
if (err) { if (err) {
resolve({ resolve({
code: 500, code: 500,
@ -215,6 +152,9 @@ app.post('/api/agv/stopRobot', async (req, res) => {
} }
}) })
// ==================================================
// 获取机械臂末端位姿 // 获取机械臂末端位姿
app.post('/api/arm/getPose', async (req, res) => { app.post('/api/arm/getPose', async (req, res) => {
const request = { const request = {

File diff suppressed because it is too large Load Diff

View File

@ -1,74 +1,72 @@
/**
* @file agv_service.proto
* @brief AGV服务的gRPC接口AGV相关命令
* gRPCAGVServiceImpl
*/
syntax = "proto3"; syntax = "proto3";
import "cmvr/api/agv_command.proto";
package cmvr.api; package cmvr.api;
import "cmvr/api/common.proto";
import "cmvr/api/agv_command.proto";
// AGV
// AGV
service AgvService { service AgvService {
// // AGV
rpc GetStatusInfo(GetAgvStatusInfoCommand.Request) returns (GetAgvStatusInfoCommand.Feedback); rpc getRuntimeState(AgvRuntimeStateCommand.Request) returns (AgvRuntimeStateCommand.Feedback);
rpc GetBatteryStatus(RobotStatusBatteryCommand.Request) returns (RobotStatusBatteryCommand.Feedback); //
rpc getNavigationStatus(AgvNavigationStatusCommand.Request) returns (AgvNavigationStatusCommand.Feedback);
rpc GetRobotLocation(RobotStatusLocCommand.Request) returns (RobotStatusLocCommand.Feedback); //
rpc emergencyStop(CommandHeader.Request) returns (CommandHeader.Feedback);
rpc RobotConfigDownloadMap(RobotConfigDownloadMapCommand.Request) returns (RobotConfigDownloadMapCommand.Feedback); //
rpc clearFault(CommandHeader.Request) returns (CommandHeader.Feedback);
// 姿姿 x/y theta
rpc navigateToPose(AgvNavigateToPoseCommand.Request) returns (AgvNavigateToPoseCommand.Feedback);
rpc GetMapStatus(RobotStatusMapCommand.Request) returns (RobotStatusMapCommand.Feedback); //
rpc navigateToStation(AgvNavigateToStationCommand.Request) returns (AgvNavigateToStationCommand.Feedback);
//
rpc followPath(AgvFollowPathCommand.Request) returns (AgvFollowPathCommand.Feedback);
rpc RobotConfigUploadMap(RobotConfigUploadMapCommand.Request) returns (RobotConfigUploadMapCommand.Feedback); //
rpc pauseNavigation(CommandHeader.Request) returns (CommandHeader.Feedback);
// //
rpc RobotConfigLock(RobotConfigLockCommand.Request) returns (RobotConfigLockCommand.Feedback); rpc resumeNavigation(CommandHeader.Request) returns (CommandHeader.Feedback);
// //
rpc GetCurrentLockStatus(RobotStatusCurrentLockCommand.Request) returns (RobotStatusCurrentLockCommand.Feedback); rpc cancelNavigation(CommandHeader.Request) returns (CommandHeader.Feedback);
// // vx/vy /wz /
rpc RobotMotionControl(RobotMotionControlCommand.Request) returns (RobotMotionControlCommand.Feedback); rpc setVelocity(AgvSetVelocityCommand.Request) returns (AgvSetVelocityCommand.Feedback);
// 2022 //
rpc RobotLoadMap(RobotLoadMapCommand.Request) returns (RobotLoadMapCommand.Feedback); rpc stopVelocityControl(CommandHeader.Request) returns (CommandHeader.Feedback);
// AGV
rpc listMaps(AgvListMapsCommand.Request) returns (AgvListMapsCommand.Feedback);
// 1022 //
rpc QueryLoadMapStatus(RobotQueryLoadMapStatusCommand.Request) returns (RobotQueryLoadMapStatusCommand.Feedback); rpc listStations(AgvListStationsCommand.Request) returns (AgvListStationsCommand.Feedback);
// 使
rpc switchMap(AgvMapCommand.Request) returns (AgvMapCommand.Feedback);
// 1301 // AGV
rpc QueryStationList(QueryStationListCommand.Request) returns (QueryStationListCommand.Feedback); rpc uploadMap(AgvMapCommand.Request) returns (AgvMapCommand.Feedback);
//
rpc downloadMap(AgvMapCommand.Request) returns (AgvMapCommand.Feedback);
// 3066 // / 2D3D
rpc RobotGoTargetList(RobotGoTargetListCommand.Request) returns (RobotGoTargetListCommand.Feedback); // AGV
rpc startMapping(AgvStartMappingCommand.Request) returns (AgvStartMappingCommand.Feedback);
// 1020 robot_status_task_req // resume_token
// 1020 robot_status_task_req // AGV update_type
rpc RobotStatusTaskCurrent(RobotStatusTaskCurrentCommand.Request) returns (RobotStatusTaskCurrentCommand.Feedback); rpc streamMap(AgvMapStreamCommand.Request) returns (stream AgvMapStreamCommand.Feedback);
// 1110 robot_status_task_status_package_req // /
rpc RobotStatusTaskPackage(RobotStatusTaskPackageCommand.Request) returns (RobotStatusTaskPackageCommand.Feedback); rpc stopMapping(CommandHeader.Request) returns (CommandHeader.Feedback);
}
// 3051 robot_task_gotarget_req 0x0BEB
rpc RobotGoTarget(RobotGoTargetCommand.Request) returns (RobotGoTargetCommand.Feedback);
// 0x07D0
rpc RobotControlStop(RobotControlStopCommand.Request) returns (RobotControlStopCommand.Feedback);
// 3001 (0x0BB9)
rpc RobotTaskPause(RobotTaskPauseCommand.Request) returns (RobotTaskPauseCommand.Feedback);
// 3002 (0x0BBA)
rpc RobotTaskResume(RobotTaskResumeCommand.Request) returns (RobotTaskResumeCommand.Feedback);
// 3003 (0x0BBB)
rpc RobotTaskCancel(RobotTaskCancelCommand.Request) returns (RobotTaskCancelCommand.Feedback);
}

View File

@ -0,0 +1,310 @@
syntax = "proto3";
package cmvr.msgs;
// AGV 姿
message AgvPose2d {
// X
double x = 1;
// Y
double y = 2;
//
double theta = 3;
}
// AGV
message AgvVelocity {
// X 线/
double vx = 1;
// Y 线/
double vy = 2;
// Z /
double wz = 3;
}
// AGV
message AgvBatteryState {
// [0, 1] 0.8 80%
double percentage = 1;
//
double voltage = 2;
// AGV
double current = 3;
//
double temperature = 4;
//
bool charging = 5;
}
//
message AgvMotionOptions {
// 线/0 使 AGV
double max_speed = 1;
// /0 使 AGV
double max_angular_speed = 2;
// 线/^20 使 AGV
double max_acceleration = 3;
// /^20 使 AGV
double max_angular_acceleration = 4;
// 0 使 AGV
double reach_distance = 5;
// 0 使 AGV
double reach_angle = 6;
// [0, 1]1
double speed_ratio = 7;
// true
bool asynchronous = 8;
}
// AGV
message AgvAdapterParams {
// 使 AGV
map<string, string> values = 1;
}
// AGV
message AgvRuntimeState {
// Unix
double timestamp = 1;
// AgvMode
int32 mode = 2;
// AGV
bool connected = 3;
//
bool localized = 4;
// AGV
bool moving = 5;
// AGV
bool fault = 6;
// AGV
bool emergency_stopped = 7;
// 姿
AgvPose2d pose = 8;
//
AgvVelocity velocity = 9;
//
AgvBatteryState battery = 10;
//
string current_map = 11;
// id
string current_station = 12;
//
string last_error = 13;
}
//
message AgvStation {
// id
string id = 1;
//
string type = 2;
// 姿
AgvPose2d pose = 3;
//
string description = 4;
}
//
message AgvPathSegment {
// id
string source_station = 1;
// id
string target_station = 2;
}
// 2D3D
// AGV
enum AgvMapDimension {
//
AGV_MAP_DIMENSION_UNSPECIFIED = 0;
// 2D
AGV_MAP_2D = 1;
// 3D
AGV_MAP_3D = 2;
// 2D 3D
AGV_MAP_2D_AND_3D = 3;
}
//
enum AgvMapUpdateType {
//
AGV_MAP_UPDATE_UNSPECIFIED = 0;
//
AGV_MAP_UPDATE_SNAPSHOT = 1;
//
AGV_MAP_UPDATE_INCREMENTAL = 2;
//
AGV_MAP_UPDATE_RESET = 3;
}
// 2D/3D
enum AgvMapObjectType {
//
AGV_MAP_OBJECT_UNSPECIFIED = 0;
//
AGV_MAP_OBJECT_STATION = 1;
// 线线线线
AGV_MAP_OBJECT_LINE = 2;
//
AGV_MAP_OBJECT_AREA = 3;
//
AGV_MAP_OBJECT_QR_TAG = 4;
//
AGV_MAP_OBJECT_REFLECTOR = 5;
//
AGV_MAP_OBJECT_BIN_LOCATION = 6;
//
AGV_MAP_OBJECT_EXTERNAL_DEVICE = 7;
}
//
message AgvMapPoint3D {
// X
double x = 1;
// Y
double y = 2;
// Z 2D 0
double z = 3;
}
// 2D index = y * width + x
message AgvUnifiedMap2D {
// "map"
string frame_id = 1;
// Unix
double timestamp = 2;
// /
double resolution = 3;
//
uint32 width = 4;
//
uint32 height = 5;
// (0, 0) /姿x/y theta
AgvPose2d origin = 6;
// -1 0 100
repeated int32 data = 7;
// 线
repeated AgvMapObject objects = 8;
}
// 3D
message AgvMapPointSample3D {
// X
double x = 1;
// Y
double y = 2;
// Z
double z = 3;
// 0
float intensity = 4;
// 线/ 0
uint32 ring = 5;
// 0
double time_offset = 6;
}
// 3D AgvUnifiedMap3D.voxel_resolution
message AgvMapVoxel3D {
// X
int32 x = 1;
// Y
int32 y = 2;
// Z
int32 z = 3;
// [0, 1] -1
float probability = 4;
}
// 3D
// normal.x * x + normal.y * y + normal.z * z + d = 0
message AgvMapPlane3D {
//
AgvMapPoint3D center = 1;
//
AgvMapPoint3D normal = 2;
//
double d = 3;
//
double radius = 4;
}
// 使
message AgvMapObject {
// id
string id = 1;
//
AgvMapObjectType type = 2;
// 使 1 线使使
repeated AgvMapPoint3D points = 3;
// 0
double heading = 4;
// AGV使
map<string, string> properties = 5;
}
// 3D
// 3D
message AgvUnifiedMap3D {
// "map"
string frame_id = 1;
// Unix
double timestamp = 2;
// / 0
double voxel_resolution = 3;
//
repeated AgvMapPointSample3D points = 4;
//
repeated AgvMapVoxel3D voxels = 5;
//
repeated AgvMapPlane3D planes = 6;
// 3D
repeated AgvMapObject objects = 7;
}
// AGV map_2d map_3d
//
message AgvUnifiedMapUpdate {
// id map_name AGV
string map_id = 1;
// id
string session_id = 2;
// 0 1
uint64 sequence = 3;
//
string resume_token = 4;
//
AgvMapDimension dimension = 5;
//
AgvMapUpdateType update_type = 6;
// "map"
string frame_id = 7;
// Unix
double timestamp = 8;
//
bool snapshot_begin = 9;
//
bool snapshot_end = 10;
// 0
uint32 chunk_index = 11;
// 0
uint32 chunk_count = 12;
oneof payload {
// 2D 2D
AgvUnifiedMap2D map_2d = 20;
// 3D 3D
AgvUnifiedMap3D map_3d = 21;
}
}
//
message AgvNavigationStatus {
// AgvTaskState
int32 state = 1;
// AgvTaskType
int32 type = 2;
// [0, 1] 0
double progress = 3;
//
string message = 4;
}

View File

@ -5,8 +5,8 @@ import request from '@/utils/request'
* @param {Object} params * @param {Object} params
* @param {string} [params.deviceId] - 设备ID默认 agv_src1100 * @param {string} [params.deviceId] - 设备ID默认 agv_src1100
*/ */
export function getCurrentMapName(params) { export function getRuntimeState(params) {
return request('/api/agv/getCurrentMapName', params, 'POST') return request('/api/agv/getRuntimeState', params, 'POST')
} }
export function getCurrentMap(params) { export function getCurrentMap(params) {

View File

@ -3,12 +3,18 @@ import { defineStore } from 'pinia'
// 唯一idrobot // 唯一idrobot
export const useRobotStore = defineStore('robot', { export const useRobotStore = defineStore('robot', {
state: () => ({ state: () => ({
ip: '192.168.0.109:50052', ip: '192.168.1.110:50052',
agvDeviceId:'agv_src2200', agvDeviceId:'src1100',
almDeviceId: 'aubo_arm', almDeviceId: 'aubo_arm',
position: { x: 0, y: 0, angle: 0 }, position: { x: 0, y: 0, theta: 0 },
battery: 100, battery: {
status: 'idle' percentage: 0.99,
voltage: -0,
current: -0,
temperature: -0,
charging: false
},
current_map: ''
}), }),
getters: { getters: {
// 获取机器人坐标 // 获取机器人坐标
@ -30,14 +36,15 @@ export const useRobotStore = defineStore('robot', {
this.almDeviceId = str this.almDeviceId = str
}, },
// 更新机器人位置 // 更新机器人位置
setPosition(x, y, angle) { setPosition(data = {}) {
this.position.x = x this.position = data
this.position.y = y
this.position.angle = angle
}, },
// 修改状态 // 修改状态
setStatus(val) { setBattery(data = {}) {
this.status = val this.battery = data
},
setCurrentMap(str = '') {
this.current_map = str
}, },
// 重置仓库 // 重置仓库
resetRobot() { resetRobot() {

View File

@ -25,7 +25,7 @@
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { getCurrentMapName } from '@/api/agv.js' import { getRuntimeState } from '@/api/agv.js'
import { useRobotStore } from '@/stores/robot' import { useRobotStore } from '@/stores/robot'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
@ -60,17 +60,17 @@ const testConnect = async () => {
robotStore.setIp(ruleForm.value.ip) robotStore.setIp(ruleForm.value.ip)
robotStore.setAgvDeviceId(ruleForm.value.agvDeviceId) robotStore.setAgvDeviceId(ruleForm.value.agvDeviceId)
robotStore.setAlmDeviceId(ruleForm.value.almDeviceId) robotStore.setAlmDeviceId(ruleForm.value.almDeviceId)
const result = await getCurrentMapName({ const result = await getRuntimeState({
ip: robotStore.ip, ip: robotStore.ip,
deviceId: ruleForm.value.agvDeviceId deviceId: ruleForm.value.agvDeviceId
}) })
loading.value = false loading.value = false
if (result.code === 200) { if (result.code === 200) {
robotStore.setPosition(result.data.pose)
robotStore.setBattery(result.data.battery)
robotStore.setCurrentMap(result.data.current_map)
router.push({ router.push({
path: '/home', path: '/home'
query: {
mapName: result.data.current_map
}
}) })
} else { } else {
ElMessage.error(result?.message || '连接服务错误') ElMessage.error(result?.message || '连接服务错误')

View File

@ -23,7 +23,7 @@
</div> </div>
</el-header> </el-header>
<el-main> <el-main>
<Chassis :mapName="mapName" v-if="activePage === 'chassis'" /> <Chassis v-if="activePage === 'chassis'" />
<MechanicalArm v-if="activePage === 'mechanicalArm'" /> <MechanicalArm v-if="activePage === 'mechanicalArm'" />
<Camera v-if="activePage === 'camera'" /> <Camera v-if="activePage === 'camera'" />
</el-main> </el-main>
@ -34,13 +34,12 @@
import Chassis from './chassis/Chassis.vue'; import Chassis from './chassis/Chassis.vue';
import MechanicalArm from './arm/MechanicalArm.vue'; import MechanicalArm from './arm/MechanicalArm.vue';
import Camera from './camera/index.vue' import Camera from './camera/index.vue'
import { useRoute, useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import autofit from 'autofit.js' import autofit from 'autofit.js'
autofit.init() autofit.init()
const router = useRouter() const router = useRouter()
const route = useRoute()
const currentTime = ref('') const currentTime = ref('')
const weekText = ref('') const weekText = ref('')
@ -79,15 +78,12 @@ const back = () => {
router.back() router.back()
} }
const mapName = ref('')
let clockTimer, binaryTimer; let clockTimer, binaryTimer;
onMounted(() => { onMounted(() => {
updateClock(); updateClock();
clockTimer = setInterval(updateClock, 1000); clockTimer = setInterval(updateClock, 1000);
animateBinary() animateBinary()
binaryTimer = setInterval(animateBinary, 400); binaryTimer = setInterval(animateBinary, 400);
mapName.value = route.query.mapName
}) })
onUnmounted(() => { onUnmounted(() => {

View File

@ -27,7 +27,7 @@
<div class="map-body"> <div class="map-body">
<!-- <canvas ref="mapCanvas" /> --> <!-- <canvas ref="mapCanvas" /> -->
<MapCanvas :mapName="mapName" :isDragging="!isDragging" /> <MapCanvas :mapName="robotStore.current_map" :isDragging="!isDragging" />
</div> </div>
</section> </section>
@ -134,12 +134,12 @@ import { useRobotStore } from '@/stores/robot'
import { moveRobot, stopRobot } from '@/api/agv.js' import { moveRobot, stopRobot } from '@/api/agv.js'
import MapCanvas from './MapCanvas.vue' import MapCanvas from './MapCanvas.vue'
const props = defineProps({ // const props = defineProps({
mapName: { // mapName: {
type: String, // type: String,
default: '' // default: ''
} // }
}) // })
// const VITE_AGV_DEVICE_ID = import.meta.env.VITE_AGV_DEVICE_ID // const VITE_AGV_DEVICE_ID = import.meta.env.VITE_AGV_DEVICE_ID
@ -168,8 +168,7 @@ const isDragging = ref(false)
const moveRobotData = ref({ const moveRobotData = ref({
vx: 0, vx: 0,
vy: 0, vy: 0,
w: 0, vz: 0
duration: -1
}) })
/* long-press stubs */ /* long-press stubs */
@ -183,10 +182,9 @@ const onPress = async (_dir) => {
} else { } else {
moveRobotData.value.vy = -maxSpeed.value moveRobotData.value.vy = -maxSpeed.value
} }
moveRobotData.value.w = rotationAngle.value moveRobotData.value.vz = rotationAngle.value
const res = await moveRobot({ const res = await moveRobot({
ip: robotStore.ip, ip: robotStore.ip,
// deviceId: VITE_AGV_DEVICE_ID,
deviceId: robotStore.agvDeviceId, deviceId: robotStore.agvDeviceId,
...moveRobotData.value ...moveRobotData.value
}) })

View File

@ -386,12 +386,11 @@ const loadSourceMap = async (mapName) => {
}) })
if (res.code === 200) { if (res.code === 200) {
try { try {
const rawJsonObject = JSON.parse(res.data.map_content); // JSON const rawJsonObject = JSON.parse(res.data); // JSON
const parsedMap = parseSmapJson(rawJsonObject); // const parsedMap = parseSmapJson(rawJsonObject); //
await loadMapIntoApplication(parsedMap); // await loadMapIntoApplication(parsedMap); //
setTimeout(() => { setTimeout(() => {
bindEvent() bindEvent()
getRobot()
}, 300) }, 300)
} catch (parseError) { } catch (parseError) {
ElMessage.error('Parse error: ' + parseError.message); // ElMessage.error('Parse error: ' + parseError.message); //
@ -417,31 +416,21 @@ const moveRobot = (robot, dx, dy, dtheta = 0) => {
robot.angle += dtheta; robot.angle += dtheta;
} }
const getRobot = async () => {
const res = await getRobotState({
ip: robotStore.ip,
// deviceId: VITE_AGV_DEVICE_ID,
deviceId: robotStore.agvDeviceId,
})
if (res.code === 200) {
robotStore.setPosition(res.data.x, res.data.y, res.data.angle)
robotStore.battery = res.data.batteryLevel
addRobot(robotStore.ip, robotStore.ip, res.data.x, res.data.y, res.data.angle, '#00D4FF')
}
}
onMounted(() => { onMounted(() => {
init() init()
}) })
watch(() => props.mapName, watch(() => props.mapName,
(newVal) => { async (newVal) => {
if (props.mapName) { if (newVal) {
loadSourceMap(props.mapName) await loadSourceMap(newVal)
addRobot(robotStore.ip, robotStore.ip, robotStore.position.x, robotStore.position.y, robotStore.position.theta, '#00D4FF')
requestAnimationFrame(renderFrame); requestAnimationFrame(renderFrame);
window.addEventListener('resize', resizeCanvasToContainer); // window.addEventListener('resize', resizeCanvasToContainer); //
resizeCanvasToContainer(); // resizeCanvasToContainer(); //
} }
}, {
immediate: true
} }
) )