package com.aros.apron.manager; import static com.aros.apron.tools.Utils.getIDJIErrorMsg; import static dji.sdk.keyvalue.key.KeyTools.createKey; import android.os.Handler; import android.os.Looper; import android.os.SystemClock; import android.util.Log; import androidx.annotation.NonNull; import com.aros.apron.base.BaseManager; import com.aros.apron.constant.AMSConfig; import com.aros.apron.entity.Movement; import com.aros.apron.entity.Osd; import com.aros.apron.tools.LogUtil; import com.aros.apron.tools.MqttManager; import com.aros.apron.tools.TakeoffProgressScheduler; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.eclipse.paho.client.mqttv3.MqttMessage; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.UUID; import dji.sdk.keyvalue.key.FlightControllerKey; import dji.v5.common.callback.CommonCallbacks; import dji.v5.common.error.IDJIError; import dji.v5.manager.KeyManager; import dji.v5.manager.aircraft.waypoint3.WaypointMissionManager; import dji.v5.manager.aircraft.waypoint3.model.BreakPointInfo; public class OSDManager extends BaseManager { private static final long INTERVAL = 1000L; private final Handler handler = new Handler(Looper.getMainLooper()); Osd.Data._$5300 _5300 = new Osd.Data._$5300(); Osd.Data data = new Osd.Data(); Osd.Data.Battery battery = new Osd.Data.Battery(); List batteries = new ArrayList<>(); Osd.Data.Battery.Batteries batterieA = new Osd.Data.Battery.Batteries(); Osd.Data.Battery.Batteries batterieB = new Osd.Data.Battery.Batteries(); List cameras = new ArrayList<>(); Osd.Data.Cameras cameraA = new Osd.Data.Cameras(); Osd.Data.Cameras.IrMeteringPoint irMeteringPoint = new Osd.Data.Cameras.IrMeteringPoint(); Osd.Data.DistanceLimitStatus distanceLimitStatus = new Osd.Data.DistanceLimitStatus(); Osd.Data.ObstacleAvoidance obstacleAvoidance = new Osd.Data.ObstacleAvoidance(); Osd.Data.PositionState positionState = new Osd.Data.PositionState(); Osd.Data.Storage storage = new Osd.Data.Storage(); Osd osd = Osd.getInstance(); // 使用GsonBuilder配置Gson实例以允许序列化特殊浮点数值 Gson gson = new GsonBuilder() .serializeSpecialFloatingPointValues() // 这是关键 .create(); private long lastExecuteTime = 0L; private final Runnable runnable = new Runnable() { @Override public void run() { long now = SystemClock.elapsedRealtime(); if (now - lastExecuteTime < INTERVAL) { handler.postDelayed(this, INTERVAL - (now - lastExecuteTime)); return; } lastExecuteTime = now; Boolean isConnect = KeyManager.getInstance().getValue(createKey(FlightControllerKey.KeyConnection)); if (!Movement.getInstance().isMissionFinish()) { if (isConnect != null && isConnect) { pushFlightAttitude(); } else { LogUtil.log(TAG, "osd stop1:flight controller is null"); } } else { LogUtil.log(TAG, "osd stop2:flight controller is null"); } // 始终基于“实际执行时间”来调度 handler.postDelayed(this, INTERVAL); } }; private OSDManager() { } public static OSDManager getInstance() { return OSDHolder.INSTANCE; } public void initOsd() { Boolean isConnect = KeyManager.getInstance().getValue(createKey(FlightControllerKey.KeyConnection)); if (isConnect != null && isConnect) { handler.postDelayed(runnable, INTERVAL); } else { LogUtil.log(TAG, "初始化飞控osd失败" + "flight controller is null"); } } public void pushFlightAttitude() { try { if (batteries != null && batteries.size() > 0) { batteries.clear(); } if (cameras != null && cameras.size() > 0) { cameras.clear(); } //相机固件? _5300.setGimbal_yaw(Movement.getInstance().getGimbal_yaw()); _5300.setGimbal_roll(Movement.getInstance().getGimbal_roll()); _5300.setGimbal_pitch(Movement.getInstance().getGimbal_pitch()); _5300.setMeasure_target_altitude(Movement.getInstance().getMeasure_target_altitude()); _5300.setMeasure_target_distance(Movement.getInstance().getMeasure_target_distance()); _5300.setMeasure_target_error_state(Movement.getInstance().getMeasure_target_error_state()); _5300.setMeasure_target_latitude(Movement.getInstance().getMeasure_target_latitude()); _5300.setMeasure_target_longitude(Movement.getInstance().getMeasure_target_longitude()); _5300.setPayload_index("53-0-0"); _5300.setThermal_current_palette_style(Movement.getInstance().getThermal_current_palette_style()); _5300.setThermal_gain_mode(Movement.getInstance().getThermal_gain_mode()); _5300.setThermal_global_temperature_max(Movement.getInstance().getThermal_global_temperature_max()); _5300.setThermal_global_temperature_min(Movement.getInstance().getThermal_global_temperature_min()); _5300.setThermal_isotherm_lower_limit(Movement.getInstance().getThermal_isotherm_lower_limit()); _5300.setThermal_isotherm_state(Movement.getInstance().getThermal_isotherm_state()); _5300.setThermal_isotherm_upper_limit(Movement.getInstance().getThermal_isotherm_upper_limit()); _5300.setVersion(1); data.set_$5300(_5300); data.setActivation_time(1); data.setAttitude_head(Movement.getInstance().getAttitude_head()); data.setAttitude_pitch(Movement.getInstance().getAttitude_pitch()); data.setAttitude_roll(Movement.getInstance().getAttitude_roll()); batterieA.setCapacity_percent(Movement.getInstance().getBattery_a_capacity_percent()); batterieA.setFirmware_version(Movement.getInstance().getBattery_a_battery_firmware_version()); batterieA.setHigh_voltage_storage_days(Movement.getInstance().getBattery_a_high_voltage_storage_days()); batterieA.setIndex(0); batterieA.setLoop_times(Movement.getInstance().getBattery_a_loop_times()); batterieA.setSn(Movement.getInstance().getBattery_a_battery_sn()); batterieA.setSub_type(Movement.getInstance().getBattery_a_sub_type()); batterieA.setType(Movement.getInstance().getBattery_a_type()); batterieA.setTemperature(Movement.getInstance().getBattery_a_temperature()); batterieA.setSub_type(Movement.getInstance().getBattery_a_sub_type()); batterieA.setVoltage(Movement.getInstance().getBattery_a_voltage()); if (Movement.getInstance().getBattery_b_capacity_percent() == 0) { batterieB.setCapacity_percent(Movement.getInstance().getBattery_a_capacity_percent()); batterieB.setFirmware_version(Movement.getInstance().getBattery_a_battery_firmware_version()); batterieB.setHigh_voltage_storage_days(Movement.getInstance().getBattery_a_high_voltage_storage_days()); batterieB.setIndex(1); batterieB.setLoop_times(Movement.getInstance().getBattery_a_loop_times()); batterieB.setSn(Movement.getInstance().getBattery_a_battery_sn()); batterieB.setSub_type(Movement.getInstance().getBattery_a_sub_type()); batterieB.setType(Movement.getInstance().getBattery_a_type()); batterieB.setTemperature(Movement.getInstance().getBattery_a_temperature()); batterieB.setSub_type(Movement.getInstance().getBattery_a_sub_type()); batterieB.setVoltage(Movement.getInstance().getBattery_a_voltage()); } else { batterieB.setCapacity_percent(Movement.getInstance().getBattery_b_capacity_percent()); batterieB.setFirmware_version(Movement.getInstance().getBattery_b_battery_firmware_version()); batterieB.setHigh_voltage_storage_days(Movement.getInstance().getBattery_b_high_voltage_storage_days()); batterieB.setIndex(1); batterieB.setLoop_times(Movement.getInstance().getBattery_b_loop_times()); batterieB.setSn(Movement.getInstance().getBattery_b_battery_sn()); batterieB.setSub_type(Movement.getInstance().getBattery_b_sub_type()); batterieB.setType(Movement.getInstance().getBattery_b_type()); batterieB.setTemperature(Movement.getInstance().getBattery_b_temperature()); batterieB.setSub_type(Movement.getInstance().getBattery_b_sub_type()); batterieB.setVoltage(Movement.getInstance().getBattery_b_voltage()); } batteries.add(batterieA); batteries.add(batterieB); battery.setBatteries(batteries); battery.setCapacity_percent(Movement.getInstance().getCapacity_percent()); battery.setLanding_power(Movement.getInstance().getLanding_power()); battery.setRemain_flight_time(Movement.getInstance().getRemain_flight_time()); battery.setReturn_home_power(Movement.getInstance().getReturn_home_power()); data.setBattery(battery); cameraA.setCamera_mode(Movement.getInstance().getCamera_mode()); cameraA.setIr_metering_mode(Movement.getInstance().getIr_metering_mode()); cameraA.setCamera_mode(Movement.getInstance().getCamera_mode()); irMeteringPoint.setTemperature(Movement.getInstance().getTemperature()); irMeteringPoint.setX(Movement.getInstance().getX()); irMeteringPoint.setY(Movement.getInstance().getY()); cameraA.setIr_metering_point(irMeteringPoint); cameraA.setIr_zoom_factor(Movement.getInstance().getIr_zoom_factor()); cameraA.setPayload_index("53-0-0"); cameraA.setPhoto_state(Movement.getInstance().getPhoto_state()); cameraA.setPhoto_storage_settings(Movement.getInstance().getPhoto_storage_settings()); cameraA.setRecord_time(Movement.getInstance().getRecord_time()); cameraA.setRecording_state(Movement.getInstance().getRecording_state()); cameraA.setRemain_photo_num(Movement.getInstance().getRemain_photo_num()); cameraA.setRemain_record_duration(Movement.getInstance().getRemain_record_duration()); cameraA.setScreen_split_enable(Movement.getInstance().isScreen_split_enable()); cameraA.setWide_exposure_mode(Movement.getInstance().getWide_exposure_mode()); cameraA.setWide_exposure_value(Movement.getInstance().getWide_exposure_value()); cameraA.setWide_iso(Movement.getInstance().getWide_iso()); cameraA.setWide_shutter_speed(Movement.getInstance().getWide_shutter_speed()); cameraA.setZoom_calibrate_farthest_focus_value(Movement.getInstance().getZoom_calibrate_farthest_focus_value()); cameraA.setZoom_calibrate_nearest_focus_value(Movement.getInstance().getZoom_calibrate_nearest_focus_value()); cameraA.setZoom_exposure_mode(Movement.getInstance().getZoom_exposure_mode()); cameraA.setZoom_exposure_value(Movement.getInstance().getZoom_exposure_value()); cameraA.setZoom_factor(Movement.getInstance().getZoom_factor()); cameraA.setZoom_focus_mode(Movement.getInstance().getZoom_focus_mode()); cameraA.setZoom_focus_state(Movement.getInstance().getZoom_focus_state()); cameraA.setZoom_focus_value(Movement.getInstance().getZoom_focus_value()); cameraA.setZoom_iso(Movement.getInstance().getZoom_iso()); cameraA.setZoom_max_focus_value(Movement.getInstance().getZoom_max_focus_value()); cameraA.setZoom_min_focus_value(Movement.getInstance().getZoom_min_focus_value()); cameraA.setZoom_shutter_speed(Movement.getInstance().getZoom_shutter_speed()); cameras.add(cameraA); data.setCameras(cameras); data.setCountry("CN"); distanceLimitStatus.setDistance_limit(Movement.getInstance().getDistance_limit()); distanceLimitStatus.setIs_near_distance_limit(Movement.getInstance().getIs_near_distance_limit()); distanceLimitStatus.setState(Movement.getInstance().getState()); data.setDistance_limit_status(distanceLimitStatus); data.setElevation(Movement.getInstance().getElevation()); data.setFirmware_version(Movement.getInstance().getFirmware_version()); data.setGear(Movement.getInstance().getGear()); data.setHeight(Movement.getInstance().getHeight()); data.setHeight_limit(Movement.getInstance().getHeight_limit()); data.setHome_distance(Movement.getInstance().getHome_distance()); data.setHorizontal_speed(Movement.getInstance().getHorizontal_speed()); data.setIs_near_area_limit(Movement.getInstance().getIs_near_area_limit()); data.setIs_near_height_limit(Movement.getInstance().getIs_near_height_limit()); data.setLatitude(Movement.getInstance().getLatitude()); data.setLongitude(Movement.getInstance().getLongitude()); data.setMode_code(Movement.getInstance().getMode_code()); data.setNight_lights_state(Movement.getInstance().getNight_lights_state()); obstacleAvoidance.setUpside(Movement.getInstance().getUpside()); obstacleAvoidance.setHorizon(Movement.getInstance().getHorizon()); obstacleAvoidance.setDownside(Movement.getInstance().getDownside()); data.setObstacle_avoidance(obstacleAvoidance); positionState.setGps_number(Movement.getInstance().getGps_number()); positionState.setIs_fixed(Movement.getInstance().getIs_fixed()); positionState.setQuality(Movement.getInstance().getQuality()); positionState.setRtk_number(Movement.getInstance().getRtk_number()); data.setPosition_state(positionState); data.setRc_lost_action(Movement.getInstance().getRc_lost_action()); data.setRid_state(Movement.getInstance().isRid_state()); data.setRth_altitude(Movement.getInstance().getRth_altitude()); storage.setUsed(Movement.getInstance().getUsed()); storage.setTotal(Movement.getInstance().getTotal()); data.setStorage(storage); data.setTotal_flight_distance(Movement.getInstance().getTotal_flight_distance()); data.setTotal_flight_sorties(Movement.getInstance().getTotal_flight_sorties()); data.setTotal_flight_time(Movement.getInstance().getTotal_flight_time()); data.setTrack_id(Movement.getInstance().getTrack_id()); data.setVertical_speed(Movement.getInstance().getVertical_speed()); data.setWind_direction(Movement.getInstance().getWind_direction()); data.setWind_speed(Movement.getInstance().getWind_speed()); Osd.Data.MaintainStatus maintainStatus = new Osd.Data.MaintainStatus(); Osd.Data.MaintainStatus.MaintainStatusArray maintainItem = new Osd.Data.MaintainStatus.MaintainStatusArray(); // state: 保养状态, enum_int, 0:无保养, 1:有保养 maintainItem.setState(0); // last_maintain_type: 上一次保养类型, enum_int, 1:基础, 2:常规, 3:深度 // 默认值给 0 表示未设置(无保养历史) maintainItem.setLast_maintain_type(1); // last_maintain_time: 上一次保养时间, date, 秒级时间戳 // 默认值 0 表示无记录 maintainItem.setLast_maintain_time(0); // last_maintain_flight_time: 上一次保养时航时, int, 单位:小时 maintainItem.setLast_maintain_flight_time(0); // last_maintain_flight_sorties: 上一次保养时架次, int maintainItem.setLast_maintain_flight_sorties(0); java.util.ArrayList maintainList = new java.util.ArrayList<>(); maintainList.add(maintainItem); maintainStatus.setMaintain_status_array(maintainList); data.setMaintain_status(maintainStatus); data.setHomepoint_latitude(Movement.getInstance().getHomepoint_latitude()); data.setHomepoint_longitude(Movement.getInstance().getHomepoint_longitude()); data.setRtk_takeoff_altitude(Movement.getInstance().getRtk_takeoff_altitude()); osd.setTid(UUID.randomUUID().toString()); osd.setBid(UUID.randomUUID().toString()); osd.setTimestamp(System.currentTimeMillis()); osd.setGateway("gateway_sn"); osd.setMethod("osd"); osd.setData(data); MqttMessage flightMessage = new MqttMessage(gson.toJson(osd).getBytes(StandardCharsets.UTF_8)); flightMessage.setQos(0); publish( MqttManager.getInstance().mqttAndroidClient, AMSConfig.UP_UAV_EVENT, flightMessage ); // Log.e(TAG,"推送osd:"+gson.toJson(osd)); } catch (Exception e) { LogUtil.log(TAG, "推送osd异常: " + e); } } private static class OSDHolder { private static final OSDManager INSTANCE = new OSDManager(); } }