zhouhn
2026-02-26 38a9356dd250d6ae39f119919028fc6f0c91ba1a
代码合并
2个文件已修改
269 ■■■■■ 已修改文件
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/protobuf/RTCmdType.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java 262 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/protobuf/RTCmdType.java
@@ -6,8 +6,11 @@
public enum RTCmdType {
    // RT CMD   云端发起CMD范围:10001~12000
    CLOUD_ORDER_OPERATION(10001),           // 云端操作订单 (云端→XPU)
    CLOUD_TASK_CONTROL(10003),              // 云端任务操作 (云端→XPU)
    CLOUD_CREATE_ORDER(10004),              // 云端新增订单 (云端→XPU)
    CLOUD_TASK_CONTROL(10002),              // 云端任务操作 (云端→XPU)
    CLOUD_CREATE_ORDER(10003),              // 云端新增订单 (云端→XPU)
    CLOUD_CANCEL_ORDER(10004),              // 云端取消订单 (云端→XPU)
    CLOUD_SEND_RT_TASK(10005),              // 云端发送新RT任务 (云端→XPU)
    CLOUD_NAVIGATION_RESPONSE(10006),       // 云端下发导航信息 (云端→XPU)
    // RT CMD   座舱发起CMD范围:12001~14000
    VEHICLE_ORDER_OPERATION(12001),         // 车端操作订单 (座舱→XPU)
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -1,6 +1,8 @@
package com.xiaopeng.automaticPilot.service;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.xiaopeng.api.dto.map.OrderRouteAndFareDto;
import com.xiaopeng.api.dto.operation.LonLatDto;
@@ -10,12 +12,16 @@
import com.xiaopeng.api.dto.pushMessage.SendMessageDTO;
import com.xiaopeng.api.feignClient.map.XpMapClient;
import com.xiaopeng.api.feignClient.operation.ReassignOrderClient;
import com.xiaopeng.api.feignClient.order.XpCruiseOrderClient;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.UserVehicleClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.order.XpCruiseOrder;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.OrderType;
import com.xiaopeng.api.vo.SystemEventType;
import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
import com.xiaopeng.api.vo.automaticPilot.protobuf.*;
import com.xiaopeng.api.vo.automaticPilot.protobuf.RTCmdType;
@@ -27,9 +33,12 @@
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.enums.OrderStatusEnum;
import com.xiaopeng.common.core.enums.PushMessageTypeEnum;
import com.xiaopeng.common.core.utils.SnowFlake;
import com.xiaopeng.common.core.utils.StringUtils;
import com.xiaopeng.common.core.utils.uuid.UUID;
import com.xiaopeng.common.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.query.Criteria;
@@ -76,7 +85,13 @@
    private UserVehicleClient userVehicleClient;
    @Resource
    private XpCruiseOrderClient xpCruiseOrderClient;
    @Resource
    private Snowflake snowflake;
    @Autowired
    private RedisService redisService;
    /**
@@ -199,11 +214,17 @@
            if(code == StatusCode.OK){
                Object sequence = redisTemplate.opsForValue().get(requestSeq);
                if(sequence!=null){
                    String[] split = sequence.toString().split("_");
                    if(split[0].equals("pushOrder")){
                    JSONObject jsonObject = JSON.parseObject(sequence.toString());
                    String event = jsonObject.getString("event");
                    //推送导航的响应消息
                    if(SystemEventType.PUSH_NAVIGATION.equals(event)){
                        String orderId = jsonObject.getString("orderId");
                        String vin = jsonObject.getString("vin");
                        String orderType = jsonObject.getString("orderType");
                        PopOrderDto dto = new PopOrderDto();
                        dto.setOrderId(Long.valueOf(split[1]));
                        dto.setXpVehicleVin(split[2]);
                        dto.setOrderId(Long.valueOf(orderId));
                        dto.setXpVehicleVin(vin);
                        dto.setOrderType(orderType);
                        xpOrderClient.popOrder(dto);
                    }
                }
@@ -381,8 +402,12 @@
        long sequence = msgContent.getHeader().getSequence();
        //开始处理消息对应的业务逻辑
        NavigationDeviationEvent deviationEvent = msgContent.getNaviDeviationEvent();
//        String requestId = deviationEvent.getRequestId();
        //TODO 没有requestId
//        String requestId = deviationEvent.getRequest_id();
        //导航id
        String routeID = "";
        Long vehicleId = null;
        String orderType = "";
        //偏航事件类型 1:请求导航,2:取消导航
//        if (deviationEvent.getEventType().equals(RtEventType.RT_EVENT_TYPE_REQUEST)) {
            NavigationDeviationMessage navigationDeviationMessage = deviationEvent.getNavigationDeviationMessage();
@@ -395,15 +420,31 @@
            LonLatDto destination = new LonLatDto();
            LonLatDto origin = new LonLatDto();
            if (orderId.contains("XU")) {
                orderType = OrderType.CRUISE_ORDER;
                // todo 下发巡游单的导航数据
                //巡游单
                origin.setLongitude(longitude);
                origin.setLatitude(latitude);
                //先响应消息
                responseMessage(sequence, "");
                //构建导航数据给到车端
                origin.setLongitude(116.40528);
                origin.setLatitude(39.90498);
                destination.setLongitude(116.40528);
                destination.setLatitude(39.90498);
                //响应消息
                responseMessage(sequence, "");
                OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
                dto.setOrderId(Long.parseLong(orderId));
                dto.setOrigin(origin);
                dto.setDestination(destination);
                R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
                if (200 != routeVoR.getCode()) {
                    throw new RuntimeException("获取订单线路和运费失败");
                }
                RouteVo routeVo = routeVoR.getData();
                routeID = routeVo.getRouteID();
//                vehicleId = xpOrder.getVehicleId();
            } else {
                orderType = OrderType.USER_ORDER;
                //正常单
                R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(Long.parseLong(orderId));
                if (200 != xpOrderR.getCode()) {
@@ -420,25 +461,45 @@
                    origin.setLatitude(latitude);
                    destination.setLongitude(xpOrder.getStartLon());
                    destination.setLatitude(xpOrder.getStartLat());
                    OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
                    dto.setOrderId(Long.parseLong(orderId));
                    dto.setOrigin(origin);
                    dto.setDestination(destination);
                    R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
                    if (200 != routeVoR.getCode()) {
                        throw new RuntimeException("获取订单线路和运费失败");
                    }
                    RouteVo routeVo = routeVoR.getData();
                    routeID = routeVo.getRouteID();
                    //缓存数据,用于后续推给乘客导航线路
                    redisService.setCacheObject("ORDER_NAVIGATION_START_DATA:" + xpOrder.getAppUserId(), com.alibaba.fastjson.JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS);
                }
                //驶往下车点的行程
                if (Arrays.asList(6).contains(xpOrder.getStatus())) {
                    //查询起点到终点的线路
                    origin.setLongitude(longitude);
                    origin.setLatitude(latitude);
                    destination.setLongitude(xpOrder.getEndLon());
                    destination.setLatitude(xpOrder.getEndLat());
                    OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
                    dto.setOrderId(Long.parseLong(orderId));
                    dto.setOrigin(origin);
                    dto.setDestination(destination);
                    R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
                    if (200 != routeVoR.getCode()) {
                        throw new RuntimeException("获取订单线路和运费失败");
                    }
                    RouteVo routeVo = routeVoR.getData();
                    routeID = routeVo.getRouteID();
                    //缓存导航数据,用于后面的逻辑中给乘客端推送导航数据
                    redisService.setCacheObject("ORDER_NAVIGATION_END_DATA:" + xpOrder.getAppUserId(), com.alibaba.fastjson.JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS);
                }
                OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
                dto.setOrderId(Long.parseLong(orderId));
                dto.setOrigin(origin);
                dto.setDestination(destination);
                R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
                if (200 != routeVoR.getCode()) {
                    throw new RuntimeException("获取订单线路和运费失败");
                }
                RouteVo routeVo = routeVoR.getData();
                R<String> stringR = xpMapClient.queryRouted(routeVo.getRouteID());
            }
            if(StringUtils.isNotEmpty(routeID)){
                XpVehicle xpVehicle = xpVehicleClient.queryById(vehicleId).getData();
                R<String> stringR = xpMapClient.queryRouted(routeID);
                if (200 != stringR.getCode()) {
                    throw new RuntimeException("根据导航ID获取车端需要的导航数据失败");
                }
@@ -461,30 +522,53 @@
        //订单类型  1:乘客订单,2=巡游订单
        LonLatDto destination = new LonLatDto();
        LonLatDto origin = new LonLatDto();
        //导航id
        String routeID = "";
        Long vehicleId = null;
        String orderType = "";
        if (orderId.contains("XU")) {
            // todo 下发巡游单的导航数据
            orderType = OrderType.CRUISE_ORDER;
            //巡游单
            if (orderPhase.equals(OrderPhase.ROUTE_TO_CRUISE)) {
                origin.setLongitude(116.40528);
                origin.setLatitude(39.90498);
                destination.setLongitude(116.40528);
                destination.setLatitude(39.90498);
                //先响应消息
                responseMessage(sequence, "");
                /* 构建导航数据给到车端 */
                R<XpCruiseOrder> cruiseOrder = xpCruiseOrderClient.getCruiseOrder(orderId);
                XpCruiseOrder xpCruiseOrder = cruiseOrder.getData();
                origin.setLongitude(xpCruiseOrder.getStartLon());
                origin.setLatitude(xpCruiseOrder.getStartLat());
                destination.setLongitude(xpCruiseOrder.getEndLon());
                destination.setLatitude(xpCruiseOrder.getEndLat());
                OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
                dto.setOrderId(Long.parseLong(orderId));
                dto.setOrigin(origin);
                dto.setDestination(destination);
                R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
                if (200 != routeVoR.getCode()) {
                    throw new RuntimeException("获取订单线路和运费失败");
                }
                RouteVo routeVo = routeVoR.getData();
                routeID = routeVo.getRouteID();
//                vehicleId = xpOrder.getVehicleId();
            }
        } else {
            orderType = OrderType.USER_ORDER;
            //正常单
            R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(Long.parseLong(orderId));
            if (200 != xpOrderR.getCode()) {
                throw new RuntimeException("订单不存在");
            }
            XpOrder xpOrder = xpOrderR.getData();
            XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData();
            //先响应消息
            responseMessage(sequence, xpVehicle.getVehicleVin());
            //驶往上车点的行程
            if (orderPhase.equals(OrderPhase.ROUTE_TO_PICKUP)) {
                XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData();
                //先响应消息
                responseMessage(sequence, xpVehicle.getVehicleVin());
                //查询车辆位置
                VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(xpVehicle.getVehicleVin())), VehiclePosition.class);
                if (Objects.isNull(vehiclePosition)) {
@@ -495,32 +579,59 @@
                origin.setLatitude(vehiclePosition.getPoint().getY());
                destination.setLongitude(xpOrder.getStartLon());
                destination.setLatitude(xpOrder.getStartLat());
                OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
                dto.setOrderId(Long.parseLong(orderId));
                dto.setOrigin(origin);
                dto.setDestination(destination);
                R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
                if (200 != routeVoR.getCode()) {
                    throw new RuntimeException("获取订单线路和运费失败");
                }
                RouteVo routeVo = routeVoR.getData();
                routeID = routeVo.getRouteID();
                //缓存数据,用于后续推给乘客导航线路
                redisService.setCacheObject("ORDER_NAVIGATION_START_DATA:" + xpOrder.getAppUserId(), com.alibaba.fastjson.JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS);
            }
            //驶往下车点的行程
            if (orderPhase.equals(OrderPhase.ROUTE_TO_DESTINATION)) {
                //查询起点到终点的线路
                origin.setLongitude(xpOrder.getStartLon());
                origin.setLatitude(xpOrder.getStartLat());
                destination.setLongitude(xpOrder.getEndLon());
                destination.setLatitude(xpOrder.getEndLat());
                //直接取缓存中的导航数据推送给车端和乘客
                Object cacheObject = redisService.getCacheObject("ORDER_NAVIGATION_DATA:" + xpOrder.getAppUserId());
                if(null == cacheObject){
                    //没有缓存数据,重新规划线路
                    //查询起点到终点的线路
                    origin.setLongitude(xpOrder.getStartLon());
                    origin.setLatitude(xpOrder.getStartLat());
                    destination.setLongitude(xpOrder.getEndLon());
                    destination.setLatitude(xpOrder.getEndLat());
                    OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
                    dto.setOrderId(Long.parseLong(orderId));
                    dto.setOrigin(origin);
                    dto.setDestination(destination);
                    R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
                    if (200 != routeVoR.getCode()) {
                        throw new RuntimeException("获取订单线路和运费失败");
                    }
                    RouteVo routeVo = routeVoR.getData();
                    routeID = routeVo.getRouteID();
                    //缓存导航数据,用于后面的逻辑中给乘客端推送导航数据
                    redisService.setCacheObject("ORDER_NAVIGATION_END_DATA:" + xpOrder.getAppUserId(), com.alibaba.fastjson.JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS);
                }else{
                    RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class);
                    routeID = routeVo.getRouteID();
                }
            }
            OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
            dto.setOrderId(Long.parseLong(orderId));
            dto.setOrigin(origin);
            dto.setDestination(destination);
            //TODO 这里的routeID不应该每次都重新生成,应该有一个缓存,调用的接口有做缓存但是没有读取缓存
            R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
            if (200 != routeVoR.getCode()) {
                throw new RuntimeException("获取订单线路和运费失败");
            }
            XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData();
            RouteVo routeVo = routeVoR.getData();
            R<String> stringR = xpMapClient.queryRouted(routeVo.getRouteID());
            vehicleId = xpOrder.getVehicleId();
        }
        if(StringUtils.isNotEmpty(routeID)){
            XpVehicle xpVehicle = xpVehicleClient.queryById(vehicleId).getData();
            R<String> stringR = xpMapClient.queryRouted(routeID);
            if (200 != stringR.getCode()) {
                throw new RuntimeException("根据导航ID获取车端需要的导航数据失败");
            }
            //构建导航下发请求对象
            cloudPushNavigationInfo(requestId, routeVo.getRouteID(), stringR.getData(), orderId, xpVehicle.getVehicleVin(), xpVehicle.getXpuId());
            cloudPushNavigationInfo(requestId, routeID, stringR.getData(), orderType, orderId, xpVehicle.getVehicleVin(), xpVehicle.getXpuId());
        }
    }
@@ -685,7 +796,6 @@
        if(orderId.contains("XU")){
            //巡游单
            //响应消息
            // TODO 1.处理结束当前巡游订单  2.创建新的巡游订单 返航  3.调用xpu车机接口  (判断是返航还是正常  返航需要存储之前的订单id)
            responseMessage(sequence, "");
            //前往目的地
            if(OrderStatusEnum.IN_SERVICE.equals(status)){
@@ -694,6 +804,50 @@
            //到达目的地
            if(OrderStatusEnum.COMPLETED.equals(status)){
                // 返程找到目前的订单 -》之前的订单 查询生成一个   正常巡游 找到下一个点位   若到达最后点位  则反向找点位  每次判断是否收车状态 是则不进行处理了
                // 找到这个订单
                R<XpCruiseOrder> cruiseOrder = xpCruiseOrderClient.getCruiseOrder(orderId);
                if(cruiseOrder!=null){
                    XpCruiseOrder xpCruiseOrder = cruiseOrder.getData();
                    Long vehicleId = xpCruiseOrder.getVehicleId();
                    // 关闭当前巡游单子 已完成
                    xpCruiseOrderClient.closeCruiseOrder(xpCruiseOrder.getVehicleVin());
                    R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(vehicleId);
                    XpVehicle xpVehicle = xpVehicleR.getData();
                    // 运营中 继续执行
                    if(xpVehicle.getOperatingStatus()==1 && xpVehicle.getState()==0){
                        // 创建新的巡游单子  判断是否为返程单子
                        if(xpCruiseOrder.getOrderType()==2){
                            R<XpCruiseOrder> lastOrder = xpCruiseOrderClient.getCruiseOrder(xpCruiseOrder.getLastOrderId());
                            XpCruiseOrder lastXpCruiseOrder = lastOrder.getData();
                            // 修改一下id 加一个一样的巡游单子
                            lastXpCruiseOrder.setId("XU"+ IdUtil.fastUUID());
                            lastXpCruiseOrder.setStatus(1);
                            xpCruiseOrderClient.addCruiseOrder(lastXpCruiseOrder);
                            com.xiaopeng.api.vo.automaticPilot.protobuf.RtTask.Builder taskBuilder = com.xiaopeng.api.vo.automaticPilot.protobuf.RtTask.newBuilder();
                            taskBuilder.setOrderId(lastXpCruiseOrder.getId());
                            taskBuilder.setTaskId("MISSION_"+ IdUtil.fastUUID());
                            taskBuilder.setTaskType(com.xiaopeng.api.vo.automaticPilot.protobuf.OrderType.ORDER_TYPE_CRUISE);
                            com.xiaopeng.api.vo.automaticPilot.protobuf.RtTask task = taskBuilder.build();
                            com.xiaopeng.api.vo.automaticPilot.protobuf.RtTaskList taskList = com.xiaopeng.api.vo.automaticPilot.protobuf.RtTaskList.newBuilder().addTasks(task).build();
                            SnowFlake snowFlake = new SnowFlake(0, 0);
                            snowFlake.withStartTimestamp(1420041600000L);
                            long sequence1 = snowFlake.nextId();
                            xpuUtil.cloudCreateOrder(taskList, xpVehicle.getVehicleVin(),sequence1);
                        }else if(xpCruiseOrder.getOrderType()==1){
                           // 正常巡游 找到下一个点位   若到达最后点位  则反向找点位 TODO v
                        }
                    }
                }
            }
        }else{
            //普通单
@@ -732,7 +886,7 @@
     * @param vin                   车辆VIN
     * @param xpuId                 XPU设备id
     */
    public void cloudPushNavigationInfo(String requestId, String routeId, String routeDataContent, String orderId, String vin, String xpuId) {
    public void cloudPushNavigationInfo(String requestId, String routeId, String routeDataContent, String orderType, String orderId, String vin, String xpuId) {
        //组装报文,将routeDateContent信息推送到XPU
        RestoreNavigationData.Builder navigationDataBuilder = RestoreNavigationData.newBuilder();
        navigationDataBuilder.setRouteId(routeId);
@@ -741,7 +895,13 @@
        navigationDataBuilder.setTimestamp(System.currentTimeMillis());
        long sequence = snowflake.nextId();
        // 处理数据
        redisTemplate.opsForValue().set(sequence,"pushOrder_"+orderId+"_"+vin,30, TimeUnit.MINUTES);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("event", SystemEventType.PUSH_NAVIGATION);
        jsonObject.put("orderType", orderType);
        jsonObject.put("orderId", orderId);
        jsonObject.put("vin", vin);
        redisTemplate.opsForValue().set(sequence, jsonObject.toJSONString(),30, TimeUnit.MINUTES);
        xpuUtil.cloudPushNavigation(navigationDataBuilder.build(), xpuId, sequence);
    }