| | |
| | | // 卫星可数 |
| | | private String differentialAge; |
| | | // 差分时间 |
| | | private String selfCheckStatus = "-1"; |
| | | // 割草机自检状态 |
| | | |
| | | private static final double METERS_PER_DEGREE_LAT = 111320.0d; |
| | | |
| | |
| | | target.positioningStatus = properties.getProperty("positioningStatus", "-1"); |
| | | target.satelliteCount = properties.getProperty("satelliteCount", "-1"); |
| | | target.differentialAge = properties.getProperty("differentialAge", "-1"); |
| | | target.selfCheckStatus = properties.getProperty("selfCheckStatus", "-1"); |
| | | } |
| | | |
| | | private void applyDefaults(Device target) { |
| | |
| | | target.positioningStatus = "-1"; |
| | | target.satelliteCount = "-1"; |
| | | target.differentialAge = "-1"; |
| | | target.selfCheckStatus = "-1"; |
| | | } |
| | | |
| | | public static synchronized Device initializeActiveDevice(String mowerId) { // 根据设备ID初始化活跃设备 |
| | |
| | | case "differentialAge": |
| | | this.differentialAge = value; |
| | | return true; |
| | | case "selfCheckStatus": |
| | | this.selfCheckStatus = value; |
| | | return true; |
| | | default: |
| | | System.err.println("未知字段: " + fieldName); |
| | | return false; |
| | |
| | | device.applyGNGGAUpdate(gnggaData, deviceId); |
| | | } |
| | | |
| | | public static synchronized void updateFromSerialGNGGA(String gnggaData) { // 串口数据更新路径(无需设备编号匹配) |
| | | Device device = gecaoji; |
| | | if (device == null) { |
| | | return; |
| | | } |
| | | device.chuankouGNGGAUpdate(gnggaData); |
| | | } |
| | | |
| | | private void applyGNGGAUpdate(String gnggaData, String deviceId) { // 执行GNGGA更新逻辑 |
| | | if (gnggaData == null) { |
| | | return; |
| | |
| | | String longitudeValue = sanitizeField(fields, 4); |
| | | String longitudeHemisphere = sanitizeField(fields, 5); |
| | | |
| | | realtimeLatitude = defaultIfEmpty(combineCoordinate(latitudeValue, latitudeHemisphere)); |
| | | realtimeLongitude = defaultIfEmpty(combineCoordinate(longitudeValue, longitudeHemisphere)); |
| | | realtimeAltitude = defaultIfEmpty(sanitizeField(fields, 9)); |
| | | 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; |
| | | } |
| | | |
| | | positioningStatus = defaultIfEmpty(sanitizeField(fields, 6)); |
| | | satelliteCount = defaultIfEmpty(sanitizeField(fields, 7)); |
| | |
| | | |
| | | updateRelativeCoordinates(latitudeValue, latitudeHemisphere, longitudeValue, longitudeHemisphere); |
| | | } |
| | | |
| | | /**串口更新GNGGA数据*/ |
| | | private void chuankouGNGGAUpdate(String gnggaData) { // 执行GNGGA更新逻辑 |
| | | if (gnggaData == null) { |
| | | return; |
| | | } |
| | | |
| | | String trimmed = gnggaData.trim(); |
| | | if (trimmed.isEmpty() || !trimmed.startsWith("$GNGGA")) { |
| | | return; |
| | | } |
| | | |
| | | String[] fields = trimmed.split(","); |
| | | if (fields.length < 15) { |
| | | System.err.println("GNGGA字段数量不足: " + fields.length); |
| | | return; |
| | | } |
| | | |
| | | |
| | | 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; |
| | | } |
| | | |
| | | String altitudeValue = sanitizeField(fields, 9); |
| | | if (hasMeaningfulValue(altitudeValue)) { |
| | | realtimeAltitude = altitudeValue; |
| | | } |
| | | |
| | | positioningStatus = defaultIfEmpty(sanitizeField(fields, 6)); |
| | | satelliteCount = defaultIfEmpty(sanitizeField(fields, 7)); |
| | | differentialAge = defaultIfEmpty(sanitizeField(fields, 13)); |
| | | realtimeSpeed ="0"; |
| | | GupdateTime = String.valueOf(System.currentTimeMillis()); |
| | | |
| | | updateRelativeCoordinates(latitudeValue, latitudeHemisphere, longitudeValue, longitudeHemisphere); |
| | | } |
| | | |
| | | private void updateRelativeCoordinates(String latValue, String latHemisphere, |
| | | String lonValue, String lonHemisphere) { // 计算相对坐标 |
| | | if (!hasMeaningfulValue(latValue) || !hasMeaningfulValue(lonValue) |
| | | || !hasMeaningfulValue(latHemisphere) || !hasMeaningfulValue(lonHemisphere)) { |
| | | realtimeX = "-1"; |
| | | realtimeY = "-1"; |
| | | return; |
| | | } |
| | | |
| | | double mowerLat = toDecimalDegrees(latValue, latHemisphere); |
| | | double mowerLon = toDecimalDegrees(lonValue, lonHemisphere); |
| | | if (Double.isNaN(mowerLat) || Double.isNaN(mowerLon)) { |
| | | realtimeX = "-1"; |
| | | realtimeY = "-1"; |
| | | return; |
| | | } |
| | | |
| | | double[] baseLatLon = resolveBaseStationLatLon(); |
| | | if (baseLatLon == null) { |
| | | realtimeX = "-1"; |
| | | realtimeY = "-1"; |
| | | return; |
| | | } |
| | | |
| | |
| | | double eastMeters = deltaLonDeg * metersPerLon; |
| | | double northMeters = deltaLatDeg * METERS_PER_DEGREE_LAT; |
| | | |
| | | realtimeX = formatMeters(eastMeters); |
| | | realtimeY = formatMeters(northMeters); |
| | | if (Double.isFinite(eastMeters) && Double.isFinite(northMeters)) { |
| | | realtimeX = formatMeters(eastMeters); |
| | | realtimeY = formatMeters(northMeters); |
| | | } |
| | | } |
| | | |
| | | private double[] resolveBaseStationLatLon() { // 解析基站经纬度 |
| | |
| | | this.differentialAge = differentialAge; |
| | | } |
| | | |
| | | public String getSelfCheckStatus() { // 获取自检状态 |
| | | return selfCheckStatus; |
| | | } |
| | | |
| | | public void setSelfCheckStatus(String selfCheckStatus) { // 设置自检状态 |
| | | this.selfCheckStatus = selfCheckStatus; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { // 输出对象信息 |
| | | return "Device{" + |
| | |
| | | ", positioningStatus='" + positioningStatus + '\'' + |
| | | ", satelliteCount='" + satelliteCount + '\'' + |
| | | ", differentialAge='" + differentialAge + '\'' + |
| | | ", selfCheckStatus='" + selfCheckStatus + '\'' + |
| | | '}'; |
| | | } |
| | | } |