张世豪
11 小时以前 ed6936545d20cc490145d2936cee4387be2afd53
src/gecaoji/Device.java
@@ -1,6 +1,7 @@
package gecaoji;
import baseStation.BaseStation;
import set.Setsys;
import zhuye.MowerLocationData;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -83,6 +84,12 @@
    // 割草机灯开关状态:1开启,0关闭,-1未知
    private String mowerBladeHeight = "-1";
    // 割草机刀盘高度:-1未知
    private String mowerWidth;
    // 割草机宽度,单位米
    private String mowerLength;
    // 割草机长度,单位米
    private String mowingSafetyDistance;
    // 割草安全距离,单位米
    private static final double METERS_PER_DEGREE_LAT = 111320.0d;
    
@@ -155,6 +162,9 @@
        if (mowerStartStatus != null) properties.setProperty("mowerStartStatus", mowerStartStatus);
        if (mowerLightStatus != null) properties.setProperty("mowerLightStatus", mowerLightStatus);
        if (mowerBladeHeight != null) properties.setProperty("mowerBladeHeight", mowerBladeHeight);
        if (mowerWidth != null) properties.setProperty("mowerWidth", mowerWidth);
        if (mowerLength != null) properties.setProperty("mowerLength", mowerLength);
        if (mowingSafetyDistance != null) properties.setProperty("mowingSafetyDistance", mowingSafetyDistance);
        
        // 保存到文件
        try (FileOutputStream output = new FileOutputStream("device.properties");
@@ -198,6 +208,9 @@
        target.mowerStartStatus = properties.getProperty("mowerStartStatus", "-1");
        target.mowerLightStatus = properties.getProperty("mowerLightStatus", "-1");
        target.mowerBladeHeight = properties.getProperty("mowerBladeHeight", "-1");
        target.mowerWidth = properties.getProperty("mowerWidth", "-1");
        target.mowerLength = properties.getProperty("mowerLength", "-1");
        target.mowingSafetyDistance = properties.getProperty("mowingSafetyDistance", "-1");
    }
    private void applyDefaults(Device target) {
@@ -233,6 +246,9 @@
        target.mowerStartStatus = "-1";
        target.mowerLightStatus = "-1";
        target.mowerBladeHeight = "-1";
        target.mowerWidth = "-1";
        target.mowerLength = "-1";
        target.mowingSafetyDistance = "-1";
    }
    public static synchronized Device initializeActiveDevice(String mowerId) { // 根据设备ID初始化活跃设备
@@ -343,6 +359,15 @@
            case "mowerBladeHeight":
                this.mowerBladeHeight = value;
                return true;
            case "mowerWidth":
                this.mowerWidth = value;
                return true;
            case "mowerLength":
                this.mowerLength = value;
                return true;
            case "mowingSafetyDistance":
                this.mowingSafetyDistance = value;
                return true;
            default:
                System.err.println("未知字段: " + fieldName);
                return false;
@@ -392,35 +417,51 @@
            mowerNumber = incomingDeviceId;
        }
        // 检查是否正在导航预览模式
        boolean isNavigating = checkIfNavigating();
        String latitudeValue = sanitizeField(fields, 2);
        String latitudeHemisphere = sanitizeField(fields, 3);
        String longitudeValue = sanitizeField(fields, 4);
        String longitudeHemisphere = sanitizeField(fields, 5);
        String combinedLatitude = combineCoordinate(latitudeValue, latitudeHemisphere);
        if (hasMeaningfulValue(combinedLatitude)) {
            realtimeLatitude = combinedLatitude;
        }
        String combinedLongitude = combineCoordinate(longitudeValue, longitudeHemisphere);
        if (hasMeaningfulValue(combinedLongitude)) {
            realtimeLongitude = combinedLongitude;
        // 只有在非导航预览模式下才更新位置相关数据
        if (!isNavigating) {
            String combinedLatitude = combineCoordinate(latitudeValue, latitudeHemisphere);
            if (hasMeaningfulValue(combinedLatitude)) {
                realtimeLatitude = combinedLatitude;
            }
            String combinedLongitude = combineCoordinate(longitudeValue, longitudeHemisphere);
            if (hasMeaningfulValue(combinedLongitude)) {
                realtimeLongitude = combinedLongitude;
            }
            String altitudeValue = sanitizeField(fields, 9);
            if (hasMeaningfulValue(altitudeValue)) {
                realtimeAltitude = altitudeValue;
            }
            // 更新位置坐标
            updateRelativeCoordinates(latitudeValue, latitudeHemisphere, longitudeValue, longitudeHemisphere);
            // 更新航向角(位置相关)
            heading = defaultIfEmpty(sanitizeField(fields, 19));
        }
        String altitudeValue = sanitizeField(fields, 9);
        if (hasMeaningfulValue(altitudeValue)) {
            realtimeAltitude = altitudeValue;
        }
        // 其他数据(电量、卫星数等)始终更新
        positioningStatus = defaultIfEmpty(sanitizeField(fields, 6));
        // 同步到绘制模块的数据源,保证往返绘制定时器能识别定位质量
        try {
            MowerLocationData.updateProperty("positioningQuality", positioningStatus);
        } catch (Throwable ignored) {
            // 防御式:即使更新失败也不影响设备数据处理
        }
        satelliteCount = defaultIfEmpty(sanitizeField(fields, 7));
        differentialAge = defaultIfEmpty(sanitizeField(fields, 13));
        battery = defaultIfEmpty(sanitizeField(fields, 16));
        pitch = defaultIfEmpty(sanitizeField(fields, 17));
        realtimeSpeed = defaultIfEmpty(sanitizeField(fields, 18));
        heading = defaultIfEmpty(sanitizeField(fields, 19));
        GupdateTime = String.valueOf(System.currentTimeMillis());
        updateRelativeCoordinates(latitudeValue, latitudeHemisphere, longitudeValue, longitudeHemisphere);
    }
    
    /**串口更新GNGGA数据*/
@@ -440,33 +481,86 @@
            return;
        }
        // 检查是否正在导航预览模式
        boolean isNavigating = checkIfNavigating();
        String latitudeValue = sanitizeField(fields, 2);
        String latitudeHemisphere = sanitizeField(fields, 3);
        String longitudeValue = sanitizeField(fields, 4);
        String longitudeHemisphere = sanitizeField(fields, 5);
        String combinedLatitude = combineCoordinate(latitudeValue, latitudeHemisphere);
        if (hasMeaningfulValue(combinedLatitude)) {
            realtimeLatitude = combinedLatitude;
        }
        String combinedLongitude = combineCoordinate(longitudeValue, longitudeHemisphere);
        if (hasMeaningfulValue(combinedLongitude)) {
            realtimeLongitude = combinedLongitude;
        // 只有在非导航预览模式下才更新位置相关数据
        if (!isNavigating) {
            String combinedLatitude = combineCoordinate(latitudeValue, latitudeHemisphere);
            if (hasMeaningfulValue(combinedLatitude)) {
                realtimeLatitude = combinedLatitude;
            }
            String combinedLongitude = combineCoordinate(longitudeValue, longitudeHemisphere);
            if (hasMeaningfulValue(combinedLongitude)) {
                realtimeLongitude = combinedLongitude;
            }
            String altitudeValue = sanitizeField(fields, 9);
            if (hasMeaningfulValue(altitudeValue)) {
                realtimeAltitude = altitudeValue;
            }
            // 更新位置坐标
            updateRelativeCoordinates(latitudeValue, latitudeHemisphere, longitudeValue, longitudeHemisphere);
            // 串口收到GNGGA数据后,触发拖尾更新
            notifyMowerTrailUpdate();
        }
        String altitudeValue = sanitizeField(fields, 9);
        if (hasMeaningfulValue(altitudeValue)) {
            realtimeAltitude = altitudeValue;
        }
        // 其他数据(电量、卫星数等)始终更新
        positioningStatus = defaultIfEmpty(sanitizeField(fields, 6));
        // 同步到绘制模块的数据源,保证往返绘制定时器能识别定位质量
        try {
            MowerLocationData.updateProperty("positioningQuality", positioningStatus);
        } catch (Throwable ignored) {
            // 防御式:即使更新失败也不影响设备数据处理
        }
        satelliteCount = defaultIfEmpty(sanitizeField(fields, 7));
        differentialAge = defaultIfEmpty(sanitizeField(fields, 13));       
        realtimeSpeed ="0";        
        GupdateTime = String.valueOf(System.currentTimeMillis());
        updateRelativeCoordinates(latitudeValue, latitudeHemisphere, longitudeValue, longitudeHemisphere);
    }
    /**
     * 通知地图渲染器更新割草机拖尾
     * 当串口收到GNGGA数据并更新位置后调用
     */
    /**
     * 检查是否正在导航预览模式
     * @return 如果正在导航预览返回true,否则返回false
     */
    private boolean checkIfNavigating() {
        try {
            dikuai.daohangyulan nav = dikuai.daohangyulan.getInstance();
            if (nav != null) {
                return nav.isNavigating();
            }
        } catch (Exception e) {
            // 如果获取导航实例失败,返回false(不影响主要功能)
        }
        return false;
    }
    private void notifyMowerTrailUpdate() {
        try {
            // 通过Shouye.getInstance()获取实例,避免循环依赖
            zhuye.Shouye shouye = zhuye.Shouye.getInstance();
            if (shouye != null) {
                zhuye.MapRenderer mapRenderer = shouye.getMapRenderer();
                if (mapRenderer != null) {
                    // 调用更新拖尾方法
                    mapRenderer.forceUpdateIdleMowerTrail();
                }
            }
        } catch (Exception e) {
            // 如果调用失败,静默处理(不影响主要功能)
            // System.err.println("通知拖尾更新失败: " + e.getMessage());
        }
    }
    private void updateRelativeCoordinates(String latValue, String latHemisphere,
@@ -498,6 +592,9 @@
        if (Double.isFinite(eastMeters) && Double.isFinite(northMeters)) {
            realtimeX = formatMeters(eastMeters);
            realtimeY = formatMeters(northMeters);
            // 保存坐标到工具类
            lujing.SavaXyZuobiao.addCoordinate(eastMeters, northMeters);
        }
    }
@@ -811,6 +908,30 @@
        this.mowerBladeHeight = mowerBladeHeight;
    }
    public String getMowerWidth() { // 获取割草机宽度
        return mowerWidth;
    }
    public void setMowerWidth(String mowerWidth) { // 设置割草机宽度
        this.mowerWidth = mowerWidth;
    }
    public String getMowerLength() { // 获取割草机长度
        return mowerLength;
    }
    public void setMowerLength(String mowerLength) { // 设置割草机长度
        this.mowerLength = mowerLength;
    }
    public String getMowingSafetyDistance() { // 获取割草安全距离
        return mowingSafetyDistance;
    }
    public void setMowingSafetyDistance(String mowingSafetyDistance) { // 设置割草安全距离
        this.mowingSafetyDistance = mowingSafetyDistance;
    }
    @Override
    public String toString() { // 输出对象信息
        return "Device{" +
@@ -842,6 +963,9 @@
                ", mowerStartStatus='" + mowerStartStatus + '\'' +
                ", mowerLightStatus='" + mowerLightStatus + '\'' +
                ", mowerBladeHeight='" + mowerBladeHeight + '\'' +
                ", mowerWidth='" + mowerWidth + '\'' +
                ", mowerLength='" + mowerLength + '\'' +
                ", mowingSafetyDistance='" + mowingSafetyDistance + '\'' +
                '}';
    }
}