机器人实时行为上报

This commit is contained in:
cbs 2025-03-13 10:19:22 +08:00
parent 9296aabd48
commit 00f611ce1c
18 changed files with 274 additions and 143 deletions

View File

@ -133,10 +133,16 @@ public class MqttFactory {
public static MqttService getMqttFactory(String topic){
DefineSubTopicEnum defineSubTopicEnum = DefineSubTopicEnum.getDefineSubTopicEnumByTopic(topic);
switch (defineSubTopicEnum){
case ROBOT_GENERICS_STATUS:
return BeanUtils.getBean(RobotGenericsStatusServiceImpl.class);
case ROBOT_STATUS:
return BeanUtils.getBean(RobotStatusServiceImpl.class);
case ROBOT_REACTIVE_STATUS:
return BeanUtils.getBean(RobotReactiveStatusServiceImpl.class);
case ROBOT_GENERICS_STATUS:
return BeanUtils.getBean(RobotGenericsStatusServiceImpl.class);
case ROBOT_PATH_STATUS:
return BeanUtils.getBean(RobotPathStatusServiceImpl.class);
case ROBOT_WORK_STATUS:
return BeanUtils.getBean(RobotWorkStatusServiceImpl.class);
case SYNCHRONOUS_ALL_MAP_REQUEST:
return BeanUtils.getBean(PathPlanningInitDataServiceImpl.class);
case TASK_ASSIGNMENT_FEEDBACK:

View File

@ -19,10 +19,12 @@ public enum DefineSubTopicEnum {
ROBOT_TASK_STATUS("ROBOT_TASK_STATUS", 0,"机器人任务完成上报"),
ROBOT_REACTIVE_STATUS("ROBOT_REACTIVE_STATUS", 0,"机器人响应式状态上报"),
ROBOT_GENERICS_STATUS("ROBOT_GENERICS_STATUS", 0,"机器人异常"),
ROBOT_PATH_STATUS("ROBOT_PATH_STATUS", 0,"导航实时行为上报"),
ROBOT_WORK_STATUS("ROBOT_WORK_STATUS", 0,"作业实时行为上报"),
SYNCHRONOUS_ALL_MAP_REQUEST("SYNCHRONOUS_ALL_MAP_REQUEST", 0,"路径规划需要初始数据上报"),
TASK_ASSIGNMENT_FEEDBACK("TASK_ASSIGNMENT_FEEDBACK", 0,"路径规划任务分配上报"),
ROBOT_TASK_MOVE ("ROBOT_TASK_MOVE ", 0,"路径规划上报实时路径"),
TASK_ASSIGNMENT_FAIL("TASK_ASSIGNMENT_FAIL", 0,"路径规划失败上报");
TASK_ASSIGNMENT_FAIL("TASK_ASSIGNMENT_FAIL", 0,"路径规划失败上报"),
ROBOT_TASK_MOVE ("ROBOT_TASK_MOVE ", 0,"路径规划上报实时路径");
private final String topic;

View File

@ -1,13 +1,11 @@
package cn.iododer.yudao.module.mqtt.framework.system;
import cn.iocoder.yudao.module.system.api.robot.RobotGenericsStatusApi;
import cn.iocoder.yudao.module.system.api.robot.RobotReactiveStatusApi;
import cn.iocoder.yudao.module.system.api.robot.RobotStatusApi;
import cn.iocoder.yudao.module.system.api.robot.RobotTaskStatusApi;
import cn.iocoder.yudao.module.system.api.robot.*;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
@EnableFeignClients(clients = {RobotGenericsStatusApi.class, RobotTaskStatusApi.class, RobotStatusApi.class, RobotReactiveStatusApi.class})
@EnableFeignClients(clients = {RobotGenericsStatusApi.class, RobotTaskStatusApi.class, RobotStatusApi.class, RobotReactiveStatusApi.class,
RobotPathStatusApi.class,RobotWorkStatusApi.class})
public class SystemConfiguration {
}

View File

@ -3,6 +3,7 @@ package cn.iododer.yudao.module.mqtt.service;
import cn.iocoder.yudao.module.system.api.robot.RobotGenericsStatusApi;
import cn.iocoder.yudao.module.system.api.robot.RobotStatusApi;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotGenericsDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotGenericsDataDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDTO;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
@ -21,7 +22,7 @@ public class RobotGenericsStatusServiceImpl implements MqttService{
@Override
public void analysisMessage(String message) {
log.info("处理RobotGenericsStatusServiceImpl的消息 :{}",message);
RobotGenericsDTO robotStatusData = JSON.parseObject(message , RobotGenericsDTO.class);
RobotGenericsDataDTO robotStatusData = JSON.parseObject(message , RobotGenericsDataDTO.class);
robotGenericsStatusApi.updateRobotCommonStatus(robotStatusData);
}
}

View File

@ -0,0 +1,22 @@
package cn.iododer.yudao.module.mqtt.service;
import cn.iocoder.yudao.module.system.api.robot.RobotPathStatusApi;
import cn.iocoder.yudao.module.system.api.robot.RobotStatusApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Slf4j
@Service
public class RobotPathStatusServiceImpl implements MqttService{
@Resource
private RobotPathStatusApi robotPathStatusApi;
@Override
public void analysisMessage(String message) {
log.info("导航实时行为上报 :{}", message);
robotPathStatusApi.robotPathStatus(message);
}
}

View File

@ -0,0 +1,20 @@
package cn.iododer.yudao.module.mqtt.service;
import cn.iocoder.yudao.module.system.api.robot.RobotReactiveStatusApi;
import cn.iocoder.yudao.module.system.api.robot.RobotWorkStatusApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class RobotWorkStatusServiceImpl implements MqttService{
@Autowired
private RobotWorkStatusApi robotWorkStatusApi;
@Override
public void analysisMessage(String message) {
log.info("作业实时行为上报 :{}", message);
robotWorkStatusApi.robotWorkStatus(message);
}
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.system.api.robot;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotGenericsDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotGenericsDataDTO;
import cn.iocoder.yudao.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -16,5 +17,5 @@ public interface RobotGenericsStatusApi {
@PostMapping(PREFIX + "/updateRobotCommonStatus")
@Operation(summary = "机器人异常上报/常规信息上报")
void updateRobotCommonStatus(@RequestBody RobotGenericsDTO robotStatusData);
void updateRobotCommonStatus(@RequestBody RobotGenericsDataDTO robotStatusData);
}

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.system.api.robot;
import cn.iocoder.yudao.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "导航实时行为上报")
public interface RobotPathStatusApi {
String PREFIX = ApiConstants.PREFIX + "/task";
@PostMapping(PREFIX + "/robotPathStatus")
@Operation(summary = "导航实时行为上报")
void robotPathStatus(@RequestParam("message") String message);
}

View File

@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.system.api.robot;
import cn.iocoder.yudao.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "作业实时行为上报")
public interface RobotWorkStatusApi {
String PREFIX = ApiConstants.PREFIX + "/task";
@PostMapping(PREFIX + "/robotWorkStatus")
@Operation(summary = "作业实时行为上报")
void robotWorkStatus(@RequestParam("message") String message);
}

View File

@ -5,7 +5,7 @@ import lombok.Data;
@Data
public class RobotGenericsDataDTO {
//车身控制器状态
private RobotHwStatesDTO hw_states;
private RobotHwStatesDTO hwStates;
//mac地址
private String mac;
private String ip;

View File

@ -8,59 +8,59 @@ import lombok.Data;
@Data
public class RobotHwStatesDTO {
//控制器状态
private String controller_state;
private String controllerState;
//转向电机角度0 为正前方逆时针正方向顺时针负
private String steer_angle;
private String steerAngle;
//转向电机驱动器错误码
private String steer_error_code;
private String steerErrorCode;
//行走电机转速m/s
private String walk_motor_vel;
private String walkMotorVel;
//行走电机电流
private String walk_motor_current;
private String walkMotorCurrent;
//行走电机温度
private String walk_motor_temperature;
private String walkMotorTemperature;
//行走电机电源单元状态
private String walk_motor_power_unit_state;
private String walkMotorPowerUnitState;
//行走电机主接触器状态
private String walk_motor_main_contactor_state;
private String walkMotorMainContactorState;
//行走电机电子制动状态
private String walk_motor_electric_brake_state;
private String walkMotorElectricBrakeState;
//行走电机锁定开关状态
private String walk_motor_lock_switch_state;
private String walkMotorLockSwitchState;
//行走电机驱动器错误码
private String walk_motor_error_code;
private String walkMotorErrorCode;
//货叉高度
private String fork_height;
private String forkHeight;
//电池的剩余容量
private String bat_soc;
private String batSoc;
//电池电流
private String bat_current;
private String batCurrent;
//电池电压
private String bat_voltage;
private String batVoltage;
//电池温度
private String bat_temperature;
private String batTemperature;
//解析后的电池故障码
private String bat_error_code;
private String batErrorCode;
//充电接触器闭合 false 为开true 为闭合
private String charge_relay_closed;
private String chargeRelayClosed;
//bms 状态电池充电中false 为放电true 为充电
private String bat_charging;
private String batCharging;
//货物到位传感器触发状态被按下则 true否则 false
private String cargo_detected;
private String cargoDetected;
//叉尖传感器触发状态物体接近触发为 true否则为 false
private String fork_tip_sensor_state;
private String forkTipSensorState;
//急停按键状态按下为 true松开为 false
private String estop_button_state;
private String estopButtonState;
//启动按键状态按下为 true松开为 false
private String start_button_state;
private String startButtonState;
//复位按键状态按下为 true松开为 false
private String reset_button_state;
private String resetButtonState;
//手动模式拨杆状态true 表示在手动状态false 为自动
private String manual_switch_state;
private String manualSwitchState;
//转向电机零位传感器状态true 为触发false 为未触发
private String steer_sensor_state;
private String steerSensorState;
//碰撞传感器触发状态触发为 true否则为 false
private String bumper_sensor_state;
private String bumperSensorState;
//灯条状态代码
private String led_state;
private String ledState;
}

View File

@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.system.api.robot;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotGenericsDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotGenericsDataDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
@ -28,30 +28,24 @@ public class RobotGenericsStatusApiImpl implements RobotGenericsStatusApi {
@Resource@Value("${zn.robot_position_cache_time:600}")
private Long robotPositionCacheTime;
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
@Override
public void updateRobotCommonStatus(RobotGenericsDTO robotStatusData) {
taskExecutor.execute(() -> {
doUpdateRobotCommonStatus(robotStatusData);
});
public void updateRobotCommonStatus(RobotGenericsDataDTO robotStatusData) {
doUpdateRobotCommonStatus(robotStatusData);
}
public void doUpdateRobotCommonStatus(RobotGenericsDTO robotStatusData) {
if (ObjectUtil.isEmpty(robotStatusData) || ObjectUtil.isEmpty(robotStatusData.getData())
|| ObjectUtil.isEmpty(robotStatusData.getData().getMac())) {
public void doUpdateRobotCommonStatus(RobotGenericsDataDTO robotStatusData) {
log.info("车机每3秒上报其他状态信息 :{}", JSONUtil.toJsonStr(robotStatusData));
if (ObjectUtil.isEmpty(robotStatusData) || ObjectUtil.isEmpty(robotStatusData.getHwStates())
|| ObjectUtil.isEmpty(robotStatusData.getMac())) {
log.info("参数不全 :{}", JSON.toJSONString(robotStatusData));
}
String mac = robotStatusData.getData().getMac();
String mac = robotStatusData.getMac();
String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC +mac;
Object object = redisUtil.get(pose2dKey);
RobotStatusDataPoseDTO robotStatusDataPoseDTO= JSONUtil.toBean((String)object, RobotStatusDataPoseDTO.class);
robotStatusDataPoseDTO.setArea(robotStatusData.getData().getZone());
robotStatusDataPoseDTO.setFloor(robotStatusData.getData().getFloor());
String batSoc = robotStatusData.getData().getHw_states().getBat_soc();
String batSoc = robotStatusData.getHwStates().getBatSoc();
if (ObjectUtil.isNotEmpty(batSoc)) {
BigDecimal a = new BigDecimal(batSoc);
BigDecimal b = new BigDecimal("100");

View File

@ -0,0 +1,79 @@
package cn.iocoder.yudao.module.system.api.robot;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.api.robot.vo.RobotPathStatusDTO;
import cn.iocoder.yudao.module.system.api.robot.vo.RobotReactiveStatusDTO;
import cn.iocoder.yudao.module.system.enums.path.PathIsReachEnum;
import cn.iocoder.yudao.module.system.service.path.PathPlanningService;
import cn.iocoder.yudao.module.system.service.robot.RobotInformationService;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@Slf4j
@RestController // 提供 RESTful API 接口 Feign 调用
@Validated
public class RobotPathStatusApiImpl implements RobotPathStatusApi {
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
@Autowired
private RobotInformationService robotInformationService;
@Resource
private PathPlanningService pathPlanningService;
/**
* 导航实时行为上报
* @param message
*/
@Override
public void robotPathStatus(String message) {
taskExecutor.execute(() -> {
doRobotPathStatus(message);
});
}
private void doRobotPathStatus(String message) {
log.info("导航实时行为上报: {}", message);
TenantContextHolder.setTenantId(1L);
RobotPathStatusDTO data = JSON.parseObject(message, RobotPathStatusDTO.class);
String robotNo = robotInformationService.getRobotNoByMac(data.getMac());
pathPlanningService.updateBehavior(data.getOrderId(), robotNo
, data.getPoseId(), data.getStatus());
}
}

View File

@ -45,18 +45,9 @@ public class RobotStatusApiImpl implements RobotStatusApi {
@Autowired
private RobotInformationService robotInformationService;
@Resource
private RobotWarnCodeMappingMapper warnCodeMappingMapper;
@Resource
private RobotWarnMsgMapper warnMsgMapper;
@Value("${zn.robot_position_cache_time:600}")
private Long robotPositionCacheTime;
@Value("${zn.robot_error_level_time:30}")
private Long robotErrorLevelTime;
@Resource
private RequestProcessor processor;
@ -66,80 +57,6 @@ public class RobotStatusApiImpl implements RobotStatusApi {
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
@Resource
private RobotWarnMsgService warnMsgService;
public void doRobotStatusUpdate(RobotStatusDTO robotStatusDataDTO) {
TenantContextHolder.setTenantId(1L);
if (ObjectUtil.isEmpty(robotStatusDataDTO) || ObjectUtil.isEmpty(robotStatusDataDTO.getMac())) {
log.info("机器人上报的信息不全 :{}", JSON.toJSONString(robotStatusDataDTO));
return;
}
String robotNo = robotInformationService.getRobotNoByMac(robotStatusDataDTO.getMac());
if (ObjectUtil.isNotNull(robotStatusDataDTO.getData().getErr_code())) {
List<RobotStatusDataErrorDTO> errCode = robotStatusDataDTO.getData().getErr_code();
if (ObjectUtil.isNull(robotNo)) {
log.info("查不到机器人编号 :{}", robotStatusDataDTO.getMac());
return;
}
List<String> warnCodes =
errCode.stream().map(RobotStatusDataErrorDTO::getErrorCode).collect(Collectors.toList());
List<RobotWarnCodeMappingDO> robotWarnCodeMappingDOS =
warnCodeMappingMapper.selectList(new LambdaQueryWrapper<RobotWarnCodeMappingDO>()
.in(RobotWarnCodeMappingDO::getWarnCode, warnCodes));
if (ObjectUtil.isEmpty(robotWarnCodeMappingDOS)) {
log.info("查不对应编号的告警信息 :{}", JSON.toJSONString(warnCodes));
return;
}
Map<String, List<RobotWarnCodeMappingDO>> warnCodeMapping =
robotWarnCodeMappingDOS.stream().collect(Collectors.groupingBy(RobotWarnCodeMappingDO::getWarnCode));
List<RobotWarnMsgDO> warnMsgDOS = new ArrayList<>();
//机器人异常等级
String errorLevelKey = RobotTaskChcheConstant.ROBOT_ERROR_LEVEL + robotStatusDataDTO.getMac();
Object errorLevel = redisUtil.get(errorLevelKey);
String errorMsgKey = RobotTaskChcheConstant.ROBOT_ERROR_MSG + robotStatusDataDTO.getMac();
Object errorMsg = redisUtil.get(errorMsgKey);
Integer level = ObjectUtil.isEmpty(errorLevel) ? 0 : Integer.valueOf(errorLevel.toString());
for (RobotStatusDataErrorDTO robotStatusData : errCode) {
List<RobotWarnCodeMappingDO> mappingDOS = warnCodeMapping.get(robotStatusData.getErrorCode());
if (ObjectUtil.isEmpty(mappingDOS)) {
log.info("当前告警类型查不到对应的告警信息 :{}", robotStatusData.getErrorCode());
continue;
}
RobotWarnMsgDO warnMsg = RobotWarnMsgDO.builder().warnLevel(Integer.valueOf(robotStatusData.getCodeLevel()))
.warnCode(robotStatusData.getErrorCode())
.robotNo(robotNo)
.warnType(RobotWarnType.ROBOT_WARN.getType())
.warnMsg(robotNo+"_"+mappingDOS.get(0).getWarnMsg())
.warnSolve(mappingDOS.get(0).getWarnSolve())
.build();
warnMsgDOS.add(warnMsg);
if (level.intValue() < Integer.valueOf(robotStatusData.getCodeLevel()).intValue()) {
level = Integer.valueOf(robotStatusData.getCodeLevel());
errorMsg = warnMsg.getWarnMsg();
}
}
redisUtil.set(errorLevelKey, level, robotErrorLevelTime);
redisUtil.set(errorMsgKey, errorMsg, robotErrorLevelTime);
warnMsgService.sendWarnMsgToWebsocket(errorMsg);
warnMsgMapper.insertBatch(warnMsgDOS);
}
}
/**
* 更新机器人点位/异常/能否做任务
*

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.system.api.robot;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.api.robot.vo.RobotWorkStatusDTO;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController // 提供 RESTful API 接口 Feign 调用
@Validated
public class RobotWorkStatusApiImpl implements RobotWorkStatusApi {
@Override
public void robotWorkStatus(String message) {
log.info("作业实时行为上报: {}", message);
TenantContextHolder.setTenantId(1L);
RobotWorkStatusDTO data = JSON.parseObject(message, RobotWorkStatusDTO.class);
}
}

View File

@ -0,0 +1,15 @@
package cn.iocoder.yudao.module.system.api.robot.vo;
import lombok.Data;
@Data
public class RobotPathStatusDTO {
/**
* mac地址
*/
public String mac;
public String poseId;
////到达"REACH",前进"MOVE“
public String status;
public String orderId;
}

View File

@ -0,0 +1,17 @@
package cn.iocoder.yudao.module.system.api.robot.vo;
import lombok.Data;
@Data
public class RobotWorkStatusDTO {
public String orderId;
public String orderType;
public String commandType;
public String workProgress;
public String executionState;
/**
* mac地址
*/
public String mac;
}

View File

@ -13,11 +13,11 @@ public class SystemJobConfiguration {
@Bean(NOTIFY_THREAD_POOL_TASK_EXECUTOR)
public ThreadPoolTaskExecutor notifyThreadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(8); // 设置核心线程数
executor.setMaxPoolSize(16); // 设置最大线程数
executor.setKeepAliveSeconds(60); // 设置空闲时间
executor.setQueueCapacity(100); // 设置队列大小
executor.setThreadNamePrefix("notify-task-"); // 配置线程池的前缀
executor.setCorePoolSize(8);
executor.setMaxPoolSize(16);
executor.setKeepAliveSeconds(60);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("notify-task-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 进行加载
executor.initialize();