puzhibing
2026-02-12 c4e76442fde2ab11f8a33b16703e40c3942811a8
合并代码
9个文件已删除
2个文件已修改
624 ■■■■■ 已修改文件
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/ActionType.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/OrderOperation.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/OrderOperationState.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/OrderOperationStatus.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/OrderOperationType.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/OrderType.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/PointType.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/TargetPoint.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/Waypoint.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java 377 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/XPUUtil.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/ActionType.java
File was deleted
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/OrderOperation.java
File was deleted
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/OrderOperationState.java
File was deleted
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/OrderOperationStatus.java
File was deleted
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/OrderOperationType.java
File was deleted
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/OrderType.java
File was deleted
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/PointType.java
File was deleted
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/TargetPoint.java
File was deleted
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudPushAddress/Waypoint.java
File was deleted
xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -1,8 +1,43 @@
package com.xiaopeng.automaticPilot.service;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.xiaopeng.api.dto.map.OrderRouteAndFareDto;
import com.xiaopeng.api.dto.operation.LonLatDto;
import com.xiaopeng.api.feignClient.map.XpMapClient;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
import com.xiaopeng.api.vo.automaticPilot.proto.down.GeoPoint;
import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.*;
import com.xiaopeng.api.vo.automaticPilot.proto.up.MessageType;
import com.xiaopeng.api.vo.automaticPilot.proto.up.MsgContent;
import com.xiaopeng.api.vo.automaticPilot.proto.up.RTCmdType;
import com.xiaopeng.api.vo.automaticPilot.proto.up.RtMsgHeader;
import com.xiaopeng.api.vo.automaticPilot.proto.up.systemStatusXpu.RealtimePose;
import com.xiaopeng.api.vo.automaticPilot.proto.up.systemStatusXpu.SystemRuntimeStatus;
import com.xiaopeng.api.vo.automaticPilot.proto.up.systemStatusXpu.VehicleStaticInfo;
import com.xiaopeng.api.vo.automaticPilot.proto.up.systemStatusXpu.Wgs;
import com.xiaopeng.api.vo.automaticPilot.proto.up.xpuNavigationRequest.NavigationRequest;
import com.xiaopeng.api.vo.automaticPilot.proto.up.xpuNavigationRequest.OrderPhase;
import com.xiaopeng.api.vo.operation.RouteVo;
import com.xiaopeng.automaticPilot.util.XPUUtil;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.utils.uuid.UUID;
import lombok.extern.slf4j.Slf4j;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
 * Kafka 消费者服务
@@ -11,36 +46,342 @@
@Service
public class KafkaConsumerService {
    @Resource
    private XpMapClient xpMapClient;
    @Resource
    private XpOrderClient xpOrderClient;
    @Resource
    private MongoTemplate mongoTemplate;
    @Resource
    private XpVehicleClient xpVehicleClient;
    @Resource
    private XPUUtil xpuUtil;
    /**
     * 消费消息 - XPU上报Robotaxi云端的消息topic(高优先级)
     *
     * @param message 消息内容
     */
    @KafkaListener(topics = "topic-prod-robotaxi-xpu-high", groupId = "group-robotaxi-xpu")
    public void consumeAutomaticPilotMessage(String message) {
        try {
            log.info("收到XPU上报高优先级主题消息: {}", message);
        } catch (Exception e) {
            log.error("处理XPU上报高优先级主题消息失败: {}", message, e);
            throw e;
    public void topicProdRobotaxiXpuHigh(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);
                    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);
                    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);
                    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);
            }
        }
    }
    /**
     * 消费消息 - XPU上报Robotaxi云端的消息topic(低优先级)
     *
     * @param message 消息内容
     */
    @KafkaListener(topics = "topic-prod-robotaxi-xpu-normal", groupId = "group-robotaxi-xpu")
    public void consumeVehicleStatusMessage(String message) {
        try {
            log.info("收到XPU上报低优先级主题消息: {}", message);
    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);
                    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);
                    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);
                    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);
            }
        } catch (Exception e) {
            log.error("处理XPU上报低优先级主题消息失败: {}", message, e);
            throw e;
        }
    }
    /**
     * XPU发布系统运行状态---车辆实时位置
     * @param msgContent
     */
    public void systemStatusXpu(MsgContent msgContent){
        SystemRuntimeStatus systemRuntimeStatus = msgContent.getContent_detail().getObject("systemRuntimeStatus", SystemRuntimeStatus.class);
        //获取实时位姿
        RealtimePose pose = systemRuntimeStatus.getPose();
        Wgs naviPose = pose.getNavi_pose();
        Double latitude = naviPose.getLatitude();
        Double longitude = naviPose.getLongitude();
        Double course = naviPose.getCourse();
        Float alt = naviPose.getAlt();
        //获取车辆静态信息
        VehicleStaticInfo staticInfo = systemRuntimeStatus.getVehicle_status().getStatic_info();
        String vin = staticInfo.getVin();
        xpVehicleClient.
        VehiclePosition vehiclePosition = new VehiclePosition();
        vehiclePosition.setVehicle_id(staticInfo.getVehicle_id());
        mongoTemplate.save()
    }
    /**
     * XPU向云端请求导航
     * @param msgContent
     */
    public void xpuNavigationRequest(MsgContent msgContent){
        NavigationRequest naviRequest = msgContent.getContent_detail().getObject("naviRequest", NavigationRequest.class);
        String orderId = naviRequest.getOrder_id();
        String taskId = naviRequest.getTask_id();
        OrderPhase orderPhase = naviRequest.getOrder_phase();
        log.info("订单ID:{}", orderId);
        log.info("任务ID:{}", taskId);
        switch (orderPhase){
            case IDLE:
                log.info("订单的任务未开始执行");
                break;
            case ROUTE_TO_PICKUP:
                log.info("驶往上车点的行程");
                buildNaviRequest(orderId, taskId, orderPhase);
                break;
            case ROUTE_TO_DESTINATION:
                log.info("驶往下车点的行程");
                break;
            case ROUTE_TO_CRUISE:
                log.info("巡游阶段路线");
                break;
        }
    }
    /**
     * 构建导航请求
     * @param orderId
     * @param taskId
     * @param orderPhase
     */
    public void buildNaviRequest(String orderId, String taskId, OrderPhase orderPhase){
        //订单类型  1:乘客订单,2=巡游订单
        Integer orderType = 1;
        LonLatDto destination = new LonLatDto();
        LonLatDto origin = new LonLatDto();
        if(orderId.contains("XU")){
            orderType = 2;
            // todo 下发巡游单的导航数据
            //巡游单
            if(orderPhase.equals(OrderPhase.ROUTE_TO_CRUISE)){
                origin.setLongitude(116.40528);
                origin.setLatitude(39.90498);
                destination.setLongitude(116.40528);
                destination.setLatitude(39.90498);
            }
        }else{
            //正常单
            R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(Long.parseLong(orderId));
            if(200 != xpOrderR.getCode()){
                throw new RuntimeException("订单不存在");
            }
            XpOrder xpOrder = xpOrderR.getData();
            //驶往上车点的行程
            if(orderPhase.equals(OrderPhase.ROUTE_TO_PICKUP)){
                XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData();
                VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("orderId").is(xpVehicle.getVehicleVin())), VehiclePosition.class);
                if(Objects.isNull(vehiclePosition)){
                    throw new RuntimeException("车辆位置信息不存在");
                }
                //查询司机当前位置到起点的线路
                origin.setLongitude(vehiclePosition.getPoint().getX());
                origin.setLatitude(vehiclePosition.getPoint().getY());
                destination.setLongitude(xpOrder.getStartLon());
                destination.setLatitude(xpOrder.getStartLat());
            }
            //驶往下车点的行程
            if(orderPhase.equals(OrderPhase.ROUTE_TO_DESTINATION)){
                //查询起点到终点的线路
                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();
            //构建导航下发请求对象
            cloudOrderOperation(orderType, orderId, taskId, routeVo);
        }
    }
    /**
     * 云端订单操作----下发导航数据
     * @param routeVo
     */
    public void cloudOrderOperation(Integer orderType, String orderId, String taskId, RouteVo routeVo){
        //构建消息体
        OrderOperation orderOperation = new OrderOperation();
        orderOperation.setOrder_id(orderId);
        orderOperation.setTask_id(taskId);
        orderOperation.setOperation_type(OrderOperationType.CLOUD_UPDATE_WAYPOINTS);
        //构建航点
        List<Waypoint> waypoints = new ArrayList<>();
        List<LonLatDto> polyline = routeVo.getPolyline();
        for (int i = 0; i < polyline.size(); i++) {
            LonLatDto lonLatDto = polyline.get(i);
            Waypoint waypoint = new Waypoint();
            waypoint.setWaypoint_id(UUID.randomUUID().toString());
            if(0 == i){
                waypoint.setPoint_type(PointType.START_POINT);
                //订单类型不同,点位的动作类型不同
                waypoint.setAction_type(1 == orderType ? ActionType.PICK_UP : ActionType.ACTION_UNSPECIFIED);
            }else if(polyline.size() - 1 == i){
                waypoint.setPoint_type(PointType.END_POINT);
                waypoint.setAction_type(1 == orderType ? ActionType.DROP_OFF : ActionType.ACTION_UNSPECIFIED);
            }else{
                waypoint.setPoint_type(PointType.WAY_POINT);
                //订单类型不同,点位的动作类型不同
                waypoint.setAction_type(ActionType.ACTION_UNSPECIFIED);
            }
            //构建经纬度
            GeoPoint geoPoint = new GeoPoint();
            geoPoint.setLongitude(lonLatDto.getLongitude());
            geoPoint.setLatitude(lonLatDto.getLatitude());
            waypoint.setPoint(geoPoint);
            waypoint.setSequence(i + 1);
            waypoints.add(waypoint);
        }
        orderOperation.setWaypoints(waypoints);
        //开发发送请求到XPU
        xpuUtil.cloudOrderOperation(orderOperation);
    }
    public void c(MsgContent msgContent){
    }
}
xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/XPUUtil.java
@@ -1,5 +1,7 @@
package com.xiaopeng.automaticPilot.util;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
@@ -81,8 +83,9 @@
        header.setMsg_id(UUID.randomUUID().toString());
        header.setTimestamp(System.currentTimeMillis());
        header.setCmd(RTCmdType.CLOUD_ORDER_OPERATION);
        header.setSequence(1L);
        header.setType(MessageType.MESSAGE_TYPE_RESPONSE);
        Snowflake snowflake = IdUtil.getSnowflake(0, 0);
        header.setSequence(snowflake.nextId());
        header.setType(MessageType.MESSAGE_TYPE_REQUEST);
        msgContent.setHeader(header);
        // 消息内容
        JSONObject jsonObject = new JSONObject();