xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/automaticPilot/VehicleBaseRespDto.java
New file @@ -0,0 +1,83 @@ package com.xiaopeng.api.dto.automaticPilot; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; @Data @Builder @AllArgsConstructor @NoArgsConstructor public class VehicleBaseRespDto implements Serializable { private static final long serialVersionUID = -1251766408952592117L; /** * 车架号 */ private String vin; /** * 大屏虚拟id(兼容旧接口) */ private String vid; /** * 大屏硬件id */ private String cduId; /** * sim卡id */ private String iccid; /** * 物料编码id */ private String vehicleMaterielId; /** * 车型code. * DB, DC, DE就是G3 * ED 就是 P7 * VehicleTypeType */ private String vehicleTypeCode; /** * 车型名称,eg:D10,D20,D21.. */ private String vehicleTypeName; /** * 对外名称,eg:1.0,G3,P5... */ private String vehicleSaleName; /** * 车牌信息(车牌号) */ private String plateNo; /** * 车辆用途 */ private Integer usage; /** * 公告车型code */ private String proclamationCode; /*** * 给实时流 */ private String batchNo; } xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/automaticPilot/XpuVimClientFallbackFactory.java
New file @@ -0,0 +1,21 @@ package com.xiaopeng.api.factory.automaticPilot; import com.xiaopeng.api.feignClient.automaticPilot.XpuVinClient; import com.xiaopeng.common.core.domain.R; import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.openfeign.FallbackFactory; @Slf4j public class XpuVimClientFallbackFactory implements FallbackFactory<XpuVinClient> { @Override public XpuVinClient create(Throwable cause) { return new XpuVinClient() { @Override public R<String> getXpuIdByVin(String vin) { log.error("查询XPUID失败: {}", cause.getMessage()); return null; } }; } } xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/automaticPilot/VmpOpenServiceClient.java
New file @@ -0,0 +1,46 @@ package com.xiaopeng.api.feignClient.automaticPilot; import com.xiaopeng.api.dto.automaticPilot.VehicleBaseRespDto; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import java.util.List; import java.util.Map; @FeignClient(name = "xp-vmp-open-boot") public interface VmpOpenServiceClient { /** * 通过vin获取车辆基本信息 * * @param vin * @return */ @GetMapping("/logan/vehicleInfo/vin") VehicleBaseRespDto getVehicleInfoByVin(@RequestParam("vin") String vin, @RequestParam("respList") List<String> respList); /** * 查询车辆绑定信息, 通过vin获取车辆xpu id * typeList类型,1:XPUID,2:待扩展 * 参数示例:?vin=TESTE290000000000&typeList=1,2 * 返回示例:{ * "1": "01010101010101010101010101010101", * "2": "xxx" * } */ @GetMapping("/logan/vehicle/bind/info/query") Map<String, String> getVehicleBindInfoByVin(@RequestParam("vin") String vin, @RequestParam("typeList") List<String> typeList); /** * 通过车辆绑定信息获取车架号, 通过xpu id获取车辆vin * type类型,1:XPUID,2:待扩展 * 参数示例:?value=00000000000000000000000000000001&type=1 * 返回示例:{ * L1NSPGHB9RB900099 * } */ @GetMapping("/logan/vehicle/bind/info/getVin") String getVinByXpuId(@RequestParam("value") String xpuId, @RequestParam("type") Integer type); } xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/automaticPilot/XpuVinClient.java
New file @@ -0,0 +1,24 @@ package com.xiaopeng.api.feignClient.automaticPilot; import com.xiaopeng.api.factory.automaticPilot.XpuVimClientFallbackFactory; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; @FeignClient(contextId = "XpuVinClient", value = ServiceNameConstantsEnum.XP_AUTOMATIC_PILOT_SERVICE, fallbackFactory = XpuVimClientFallbackFactory.class) public interface XpuVinClient { /** * 根据车辆VIN查询XPUID * @param vin * @return */ @GetMapping("/xpu/getXpuIdByVin") R<String> getXpuIdByVin(@RequestParam("vin") String vin); } xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/vehicleConvoy/XpVehicleClient.java
@@ -79,4 +79,16 @@ */ @GetMapping("/inner/vehicle/findByVehicleVin") R<XpVehicle> findByVehicleVin(@RequestParam("vehicleVin") String vehicleVin); /** * 根据车辆xpuid查询车辆信息 * * @param xpuid * @return */ @GetMapping("/inner/vehicle/findByVehicleXpuId") R<XpVehicle> findByVehicleXpuId(@RequestParam("xpuid") String xpuid); } xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/vehicleConvoy/XpVehicle.java
@@ -40,6 +40,9 @@ @ApiModelProperty(value = "车辆vin码") private String vehicleVin; @ApiModelProperty(value = "车辆xpuid") private String xpuId; @ApiModelProperty(value = "车牌号") private String plateNumber; xp-robotaxi-api/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -23,4 +23,5 @@ com.xiaopeng.api.factory.account.UserResourcesClientFallbackFactory com.xiaopeng.api.factory.vehicleConvoy.VehicleControlClientFallbackFactory com.xiaopeng.api.factory.automaticPilot.XPUClientFallbackFactory com.xiaopeng.api.factory.automaticPilot.XpuVimClientFallbackFactory com.xiaopeng.api.factory.maintenance.XpCheckLocationClientFallbackFactory xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/KafkaTestController.java
@@ -1,21 +1,14 @@ package com.xiaopeng.automaticPilot.controller; import com.alibaba.fastjson2.JSON; import com.xiaopeng.api.vo.automaticPilot.proto.up.MsgContent; import com.xiaopeng.automaticPilot.service.KafkaConsumerService; import io.swagger.annotations.Api; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.kafka.annotation.KafkaListener; import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.RestController; /** * Kafka 测试控制器 */ @Slf4j @RestController @RequestMapping("/kafka") @Api(tags = "Kafka 测试接口") public class KafkaTestController { @Autowired @@ -31,13 +24,8 @@ */ @KafkaListener(topics = "topic-prod-robotaxi-xpu-high", groupId = "group-robotaxi-xpu") public void topicProdRobotaxiXpuHigh(String message) { try { log.info("收到XPU上报高优先级主题消息: {}", message); kafkaConsumerService.topicProdRobotaxiXpuHigh(message); } catch (Exception e) { log.error("处理XPU上报高优先级主题消息失败: {}", message, e); throw e; } log.info("收到XPU上报高优先级主题消息: {}", message); kafkaConsumerService.topicProdRobotaxiXpuHigh(message); } /** @@ -47,12 +35,7 @@ */ @KafkaListener(topics = "topic-prod-robotaxi-xpu-normal", groupId = "group-robotaxi-xpu") public void topicProdRobotaxiXpuNormal(String message) { try { log.info("收到XPU上报低优先级主题消息: {}", message); kafkaConsumerService.topicProdRobotaxiXpuNormal(message); } catch (Exception e) { log.error("处理XPU上报低优先级主题消息失败: {}", message, e); throw e; } log.info("收到XPU上报低优先级主题消息: {}", message); kafkaConsumerService.topicProdRobotaxiXpuNormal(message); } } xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/XpuVinController.java
New file @@ -0,0 +1,31 @@ package com.xiaopeng.automaticPilot.controller; import com.xiaopeng.automaticPilot.util.XPUUtil; import com.xiaopeng.common.core.domain.R; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController @RequestMapping("") public class XpuVinController { @Resource private XPUUtil xpuUtil; /** * 根据车辆VIN查询XPUID * @param vin * @return */ @GetMapping("/xpu/getXpuIdByVin") public R<String> getXpuIdByVin(@RequestParam("vin") String vin){ String xpuId = xpuUtil.getXpuIdByVin(vin); return R.ok(xpuId); } } xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -89,6 +89,24 @@ */ public void topicProdRobotaxiXpuHigh(String message) { MsgContent msgContent = JSON.parseObject(message, MsgContent.class); handleXPUMessage(msgContent, message); } /** * 消费消息 - XPU上报Robotaxi云端的消息topic(低优先级) */ public void topicProdRobotaxiXpuNormal(String message) { MsgContent msgContent = JSON.parseObject(message, MsgContent.class); handleXPUMessage(msgContent, message); } /** * 处理XPU消息 * @param msgContent * @param message */ public void handleXPUMessage(MsgContent msgContent, String message){ RtMsgHeader header = msgContent.getHeader(); MessageType type = header.getType(); //处理请求消息 @@ -173,87 +191,12 @@ xpOrderClient.popOrder(dto); } } } } } /** * 消费消息 - XPU上报Robotaxi云端的消息topic(低优先级) */ public void topicProdRobotaxiXpuNormal(String message) { MsgContent msgContent = JSON.parseObject(message, MsgContent.class); RtMsgHeader header = msgContent.getHeader(); MessageType type = header.getType(); //处理请求消息 if (MessageType.MESSAGE_TYPE_REQUEST == type) { //区分业务类型 RTCmdType cmd = header.getCmd(); switch (cmd) { case SYSTEM_STATUS_XPU: log.info("XPU发布系统运行状态 (XPU→云端):{}", message); systemStatusXpu(msgContent); break; case XPU_NAVIGATION_REQUEST: log.info("XPU向云端请求导航 (XPU→云端):{}", message); xpuNavigationRequest(msgContent); break; case TRIP_STATUS_UPDATE_EVENT: log.info("行程状态更新(XPU→云端)(XPU→座舱):{}", message); break; case PULLOVER_STATUS_EVENT: log.info("靠边停车状态(XPU→云端)(XPU→座舱):{}", message); break; case DRIVING_MODE_UPDATE_EVENT: log.info("驾驶模式变化(XPU→云端)(XPU→座舱):{}", message); break; case SYSTEM_STATUS_UPDATE_EVENT: log.info("系统状态变化(XPU→云端)(XPU→座舱):{}", message); break; case TASK_STATE_UPDATE_EVENT: log.info("任务状态变化(XPU→云端)(XPU→座舱):{}", message); break; case ORDER_STATE_UPDATE_EVENT: log.info("订单状态变化(XPU→云端)(XPU→座舱):{}", message); orderStateUpdateEvent(msgContent); break; case POINT_ARRIVAL_STATUS_EVENT: log.info("到达目标点状态(XPU→云端)(XPU→座舱):{}", message); break; case PICKUP_CONFIRMATION_EVENT: log.info("用户上车确认(XPU→云端)(XPU→座舱):{}", message); break; case DROPOFF_INFO_EVENT: log.info("用户下车信息(XPU→云端):{}", message); break; case NAVIGATION_DEVIATION_EVENT: log.info("导航偏航(XPU→云端):{}", message); navigationDeviationEvent(msgContent); break; case EMERGENCY_STOP_EVENT: log.info("急停(XPU→云端)(XPU→座舱):{}", message); break; case NAVIGATION_UPDATE_EVENT: log.info("导航信息变化(XPU→云端):{}", message); break; case TASK_QUEUE_UPDATE_EVENT: log.info("XPU待执行任务队列(XPU→云端):{}", message); break; case SYSTEM_STATE_ANAPSHOT_SYNC_EVENT: log.info("每次MQTT连接之后触发 (XPU→云端):{}", message); break; case ORDER_STATE_UPDATE_TO_CDU_EVENT: log.info("更新订单状态到CDU (XPU→云端):{}", message); break; default: log.info("消息不在处理范围内,忽略:{}", message); } } } /** @@ -273,7 +216,9 @@ Float alt = naviPose.getAlt(); //获取车辆静态信息 VehicleStaticInfo staticInfo = systemRuntimeStatus.getVehicle_status().getStatic_info(); String vin = staticInfo.getVin(); String xpuId = staticInfo.getXpu_id(); XpVehicle xpVehicle = xpVehicleClient.findByVehicleXpuId(xpuId).getData(); String vin = xpVehicle.getVehicleVin(); //先响应消息 Long sequence = msgContent.getHeader().getSequence(); responseMessage(sequence, vin); xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/XPUUtil.java
@@ -8,16 +8,23 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson2.JSON; import com.xiaopeng.api.dto.automaticPilot.MqttPublishDto; import com.xiaopeng.api.feignClient.automaticPilot.VmpOpenServiceClient; import com.xiaopeng.api.feignClient.automaticPilot.XPUClient; import com.xiaopeng.api.vo.automaticPilot.MqttPublishVo; import com.xiaopeng.api.vo.automaticPilot.proto.down.*; import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudCreateOrder.RTTask; import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.OrderOperation; import com.xiaopeng.common.core.exception.ServiceException; import com.xiaopeng.common.core.utils.StringUtils; import com.xiaopeng.common.core.utils.uuid.UUID; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; /** * 自动驾驶接口对接文档 @@ -28,6 +35,15 @@ @Resource private XPUClient xpuClient; @Resource private VmpOpenServiceClient vmpOpenServiceClient; // 查询车管绑定类型,1:XPUID,2:待扩展 public static final String XPU_ID_TYPE = "1"; // 查询车管 车辆xpuid信息返回字段,用于按需返回字段 public static final List<String> TYPE_LIST = Collections.singletonList("1"); /** @@ -51,10 +67,11 @@ jsonObject.put("task", task); msgContent.setContent_detail(jsonObject); log.info("云端-->XPU 创建订单:{}", msgContent); //根据车辆VIN查询XPUID String xpuId = getXpuIdByVin(vin); //组装请求消息体 MqttPublishVo vo = new MqttPublishVo(); vo.setTopic("topic-prod-xpu-robotaxi-high/" + vin); vo.setTopic("topic-prod-xpu-robotaxi-high/" + xpuId); vo.setPayload(JSON.toJSONString(msgContent)); return xpuClient.publish(vo); } @@ -82,14 +99,12 @@ jsonObject.put("operation", operation); msgContent.setContent_detail(jsonObject); log.info("云端-->XPU 操作订单:{}", msgContent); //根据车辆VIN查询XPUID String xpuId = getXpuIdByVin(vin); //组装请求消息体 MqttPublishVo vo = new MqttPublishVo(); vo.setTopic("topic-prod-xpu-robotaxi-high/" + vin); vo.setTopic("topic-prod-xpu-robotaxi-high/" + xpuId); vo.setPayload(JSON.toJSONString(msgContent)); return xpuClient.publish(vo); } @@ -118,11 +133,32 @@ jsonObject.put("resposne", responseMessage); msgContent.setContent_detail(jsonObject); log.info("云端-->XPU 响应消息:{}", msgContent); //根据车辆VIN查询XPUID String xpuId = getXpuIdByVin(vin); //组装请求消息体 MqttPublishVo vo = new MqttPublishVo(); vo.setTopic("topic-prod-xpu-robotaxi-high/" + vin); vo.setTopic("topic-prod-xpu-robotaxi-high/" + xpuId); vo.setPayload(JSON.toJSONString(msgContent)); return xpuClient.publish(vo); } /** * @description: 根据vin查询xpuId * @param: vin * @return: xpuId */ public String getXpuIdByVin(String vin) { Map<String, String> xpuIdMapping = vmpOpenServiceClient.getVehicleBindInfoByVin(vin, TYPE_LIST); log.info("getMqttPublishTopic vin,{},xpuIdMapping,{}", vin, JSON.toJSONString(xpuIdMapping)); if (xpuIdMapping == null || StringUtils.isEmpty(xpuIdMapping.get(XPU_ID_TYPE)) ) { log.error("根据vin查询车辆xpuid信息为空,vin={}", vin); throw new RuntimeException("根据vin查询车辆xpuid信息为空"); } return xpuIdMapping.get(XPU_ID_TYPE); } } xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
@@ -404,6 +404,20 @@ XpVehicle xpVehicle = xpVehicleService.getOne(new LambdaQueryWrapper<XpVehicle>().eq(XpVehicle::getVehicleVin, vehicleVin)); return R.ok(xpVehicle); } /** * 根据XPUID查询车辆信息 * @param xpuid * @return */ @GetMapping("/inner/vehicle/findByVehicleXpuId") public R<XpVehicle> findByVehicleXpuId(@RequestParam("xpuid") String xpuid){ XpVehicle xpVehicle = xpVehicleService.getOne(new LambdaQueryWrapper<XpVehicle>().eq(XpVehicle::getXpuId, xpuid)); return R.ok(xpVehicle); } /** * 查询可改派的车辆列表 * xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xiaopeng.api.dto.vehicleConvoy.VehicleTemperatureDto; import com.xiaopeng.api.feignClient.automaticPilot.XpuVinClient; import com.xiaopeng.api.feignClient.operation.XpElectronicClient; import com.xiaopeng.api.feignClient.order.XpOrderClient; import com.xiaopeng.api.model.operation.XpElectronicFence; @@ -37,6 +38,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.*; @@ -65,6 +67,9 @@ @Autowired private IXpVehicleAnnualRecordService xpVehicleAnnualRecordService; @Resource private XpuVinClient xpuVinClient; @Override public List<XpVehicle> listByIds(List<Long> ids) { @@ -191,6 +196,10 @@ xpVehicle.setStatus(1); // 设置入库时间 xpVehicle.setWarehousingTime(LocalDateTime.now()); //绑定XPUID String vin = xpVehicle.getVehicleVin(); String xpuid = xpuVinClient.getXpuIdByVin(vin).getData(); xpVehicle.setXpuId(xpuid); this.save(xpVehicle); } @@ -200,6 +209,10 @@ // DTO转实体 XpVehicle xpVehicle = new XpVehicle(); BeanUtil.copyProperties(dto, xpVehicle); //绑定XPUID String vin = xpVehicle.getVehicleVin(); String xpuid = xpuVinClient.getXpuIdByVin(vin).getData(); xpVehicle.setXpuId(xpuid); this.updateById(xpVehicle); }