liujie
2026-05-20 581646569a0273486c742a60961ecd98e60c6773
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package com.xiaopeng.automaticPilot.controller;
 
 
import com.xiaopeng.api.feignClient.map.AdcFencePushClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.automaticPilot.dto.CheckL4AvailableRequest;
import com.xiaopeng.automaticPilot.dto.L4CapabilityVO;
import com.xiaopeng.automaticPilot.dto.XpCommonResponse;
import com.xiaopeng.automaticPilot.dto.XpuInitStatusRequest;
import com.xiaopeng.automaticPilot.config.AutopilotProperties;
import com.xiaopeng.automaticPilot.util.XPUUtil;
import com.xiaopeng.common.core.domain.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
 
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
 
@Slf4j
@RestController
@RequestMapping("")
public class XpuVinController {
 
    @Resource
    private XPUUtil xpuUtil;
 
    @Resource
    private XpVehicleClient xpVehicleClient;
 
    @Resource
    private AutopilotProperties autopilotProperties;
 
    @Autowired
    private AdcFencePushClient adcFencePushClient;
 
 
    /**
     * 根据车辆VIN查询XPUID
     * @param vin
     * @return
     */
    @GetMapping("/logan/xpu/getXpuIdByVin")
    public R<String> getXpuIdByVin(@RequestParam("vin") String vin){
        String xpuId = xpuUtil.getXpuIdByVinForVehicleControl(vin);
        return R.ok(xpuId);
    }
 
    /**
     * 判断车辆是否能启动L4自动驾驶能力
     */
    @PostMapping("/xpu/v1/autopilot/L4/checkAvailable")
    public XpCommonResponse<L4CapabilityVO> checkL4Available(@RequestBody @Valid CheckL4AvailableRequest request) {
        log.info("Check L4 available request: {}", request);
        L4CapabilityVO vo = new L4CapabilityVO();
        vo.setVin(request.getVin());
        vo.setUid(request.getUserId());
        
        List<String> capabilities = new ArrayList<>();
        // 默认支持VPD
        capabilities.add("VPD");
        
        try {
            R<XpVehicle> vehicleR = xpVehicleClient.findByVehicleVin(request.getVin());
            if (vehicleR != null && vehicleR.getCode() == 200 && vehicleR.getData() != null) {
                XpVehicle vehicle = vehicleR.getData();
                // 车辆类型:1=待完善 2=运营车辆
                // 只有运营车辆才支持RT
                if (Objects.equals(vehicle.getVehicleType(), 2)) {
                    capabilities.add("RT");
                }
            } else {
                log.warn("Vehicle not found for vin: {}", request.getVin());
            }
        } catch (Exception e) {
            log.error("Error querying vehicle info", e);
        }
        
        vo.setL4Capability(capabilities);
        vo.setConfig(autopilotProperties);
        return XpCommonResponse.ok(vo);
    }
 
    /**
     * XPU初始化状态上报
     */
    @PostMapping("/xpu/v1/autopilot/L4/init")
    public XpCommonResponse<Void> initXpuStatus(@RequestBody @Valid XpuInitStatusRequest request) {
        log.info("XPU init status report: {}", request);
 
        // 校验车端地图版本是否最新,版本不一致或未下载均设置运营状态为4(异常),但始终返回成功
        try {
            R<String> versionR = adcFencePushClient.getMapVersion(request.getVin());
            if (versionR != null && versionR.getCode() == 200 && versionR.getData() != null) {
                String serverVersion = versionR.getData();
                String clientVersion = request.getRobotaxiAreaInfo().getMapVersion();
                if (!serverVersion.equals(clientVersion)) {
                    log.warn("车端地图版本不一致, vin={}, clientVersion={}, serverVersion={}",
                            request.getVin(), clientVersion, serverVersion);
                    setVehicleAbnormal(request.getVin());
                    return XpCommonResponse.ok(null);
                }
            }
        } catch (Exception e) {
            log.error("查询地图版本失败, vin={}", request.getVin(), e);
        }
 
        if (Boolean.FALSE.equals(request.getRobotaxiAreaInfo().getDownloaded())) {
            setVehicleAbnormal(request.getVin());
        }
        return XpCommonResponse.ok(null);
    }
 
    private void setVehicleAbnormal(String vin) {
        try {
            R<XpVehicle> vehicleR = xpVehicleClient.findByVehicleVin(vin);
            if (vehicleR != null && vehicleR.getCode() == 200 && vehicleR.getData() != null) {
                XpVehicle vehicle = vehicleR.getData();
                vehicle.setOperatingStatus(4);
                xpVehicleClient.updateVehicleById(vehicle);
                log.info("Vehicle operatingStatus set to 4 (abnormal), vin: {}", vin);
            } else {
                log.warn("Vehicle not found when updating operatingStatus, vin: {}", vin);
            }
        } catch (Exception e) {
            log.error("Failed to update vehicle operatingStatus, vin: {}", vin, e);
        }
    }
}